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

Enable razor UTs in-memory compilation #9190

Merged
merged 20 commits into from Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -428,7 +428,6 @@ public async Task SonarCompilationStartAnalysisContext_RegisterSymbolStartAction
public void DisabledRules_ForRazor_DoNotRaise(string ruleId, string extension) =>
new VerifierBuilder()
.AddAnalyzer(() => new DummyAnalyzerWithLocation(ruleId, DiagnosticDescriptorFactory.MainSourceScopeTag))
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.AddSnippet(Snippet(extension), $"SomeFile.{extension}")
.VerifyNoIssueReported();

Expand All @@ -450,7 +449,6 @@ public void AllScopedRules_ForRazor_Raise(string extension)
var keyword = extension == "razor" ? "code" : "functions";
new VerifierBuilder()
.AddAnalyzer(() => new DummyAnalyzerWithLocation("DummyId", DiagnosticDescriptorFactory.TestSourceScopeTag, DiagnosticDescriptorFactory.MainSourceScopeTag))
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.AddSnippet($$"""
@{{keyword}}
{
Expand Down
Expand Up @@ -33,21 +33,15 @@ public class AvoidLambdaExpressionInLoopsInBlazorTest

[TestMethod]
public void AvoidLambdaExpressionInLoopsInBlazor_Blazor() =>
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.razor").Verify();

[TestMethod]
public void AvoidLambdaExpressionInLoopsInBlazor_BlazorLoopsWithNoBody() =>
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.LoopsWithNoBody.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.LoopsWithNoBody.razor").Verify();

[TestMethod]
public void AvoidLambdaExpressionInLoopsInBlazor_UsingRenderFragment() =>
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.RenderFragment.razor", "AvoidLambdaExpressionInLoopsInBlazor.RenderFragmentConsumer.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("AvoidLambdaExpressionInLoopsInBlazor.RenderFragment.razor", "AvoidLambdaExpressionInLoopsInBlazor.RenderFragmentConsumer.razor").Verify();

[TestMethod]
public void AvoidLambdaExpressionInLoopsInBlazor_CS() =>
Expand Down
Expand Up @@ -33,20 +33,17 @@ public class BlazorQueryParameterRoutableComponentTest
[TestMethod]
public void BlazorQueryParameterRoutableComponent_Blazor() =>
builder.AddPaths("BlazorQueryParameterRoutableComponent.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

[TestMethod]
public void BlazorQueryParameterRoutableComponent_BlazorNoRoute() =>
builder.AddPaths("BlazorQueryParameterRoutableComponent_NoRoute.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

[TestMethod]
public void BlazorQueryParameterRoutableComponent_Partial() =>
builder.AddPaths("BlazorQueryParameterRoutableComponent_Partial.razor.cs",
"BlazorQueryParameterRoutableComponent_Partial.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

[TestMethod]
Expand Down
Expand Up @@ -69,7 +69,6 @@ public class Derived: Base
}
""")
.AddPaths("CastShouldNotBeDuplicated.cshtml")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -49,9 +49,9 @@ public class CollectionPropertiesShouldBeReadOnlyTest

[TestMethod]
public void CollectionPropertiesShouldBeReadOnly_Razor() =>
builder.AddPaths("CollectionPropertiesShouldBeReadOnly.razor", "CollectionPropertiesShouldBeReadOnly.razor.cs")
.Verify();
builder.AddPaths("CollectionPropertiesShouldBeReadOnly.razor", "CollectionPropertiesShouldBeReadOnly.razor.cs").Verify();

#endif

}
}
Expand Up @@ -73,7 +73,6 @@ public void Method()
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -74,8 +74,9 @@ public void Method()
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif

}
}
Expand Up @@ -76,7 +76,6 @@ public void Method(int a, int b)
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -75,7 +75,6 @@ public void Method()
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -73,7 +73,6 @@ public int Method(int j)
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -40,7 +40,7 @@ public class JSInvokableMethodsShouldBePublicTest
public void JSInvokableMethodsShouldBePublic_Razor() =>
builder
.AddPaths("JSInvokableMethodsShouldBePublic.razor", "JSInvokableMethodsShouldBePublic.razor.cs")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.WithOptions(ParseOptionsHelper.FromCSharp9)
.Verify();

[TestMethod]
Expand Down
Expand Up @@ -63,7 +63,6 @@ public class MethodOverloadOptionalParameterTest
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif
Expand Down
Expand Up @@ -33,15 +33,11 @@ public class ParameterTypeShouldMatchRouteTypeConstraintTest

[TestMethod]
public void ParameterTypeShouldMatchRouteTypeConstraint_Blazor() =>
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.razor").Verify();

[TestMethod]
public void ParameterTypeShouldMatchRouteTypeConstraint_Partial() =>
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.Partial.razor", "ParameterTypeShouldMatchRouteTypeConstraint.Partial.razor.cs")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.Partial.razor", "ParameterTypeShouldMatchRouteTypeConstraint.Partial.razor.cs").Verify();

[TestMethod]
public void ParameterTypeShouldMatchRouteTypeConstraint_CS() =>
Expand All @@ -52,9 +48,7 @@ public class ParameterTypeShouldMatchRouteTypeConstraintTest

[TestMethod]
public void ParameterTypeShouldMatchRouteTypeConstraint_Conversion() =>
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.Conversion.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddPaths("ParameterTypeShouldMatchRouteTypeConstraint.Conversion.razor").Verify();
}

#endif
Expand Up @@ -55,9 +55,7 @@ public class SingleStatementPerLineTest
void DoSomething(bool flag) { if (flag) Console.WriteLine("Test"); } // Noncompliant
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
"SomeRazorFile.razor").Verify();

#endif

Expand Down
Expand Up @@ -112,9 +112,7 @@ public class PublicMethodArgumentsShouldBeCheckedForNullTest

[TestMethod]
public void PublicMethodArgumentsShouldBeCheckedForNull_Roslyn_Razor() =>
roslynCS.AddPaths("PublicMethodArgumentsShouldBeCheckedForNull.razor", "PublicMethodArgumentsShouldBeCheckedForNull_component.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
roslynCS.AddPaths("PublicMethodArgumentsShouldBeCheckedForNull.razor", "PublicMethodArgumentsShouldBeCheckedForNull_component.razor").Verify();

#endif

Expand Down
Expand Up @@ -59,8 +59,9 @@ public void Method()
}
""",
"SomeRazorFile.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

#endif

}
}
22 changes: 7 additions & 15 deletions analyzers/tests/SonarAnalyzer.Test/Rules/UnnecessaryUsingsTest.cs
Expand Up @@ -53,42 +53,34 @@ public class UnnecessaryUsingsTest
[DataRow("_viewimports.cshtml")]
[DataRow("_viEwiMpoRts.cshtml")]
public void UnnecessaryUsings_RazorViewImportsCshtmlFile_NoIssueReported(string fileName) =>
builder
.AddSnippet(@"@using System.Text.Json;", fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyNoIssueReported();
builder.AddSnippet(@"@using System.Text.Json;", fileName).VerifyNoIssueReported();

[DataTestMethod]
[DataRow("_Imports.razor")]
[DataRow("_imports.razor")]
[DataRow("_iMpoRts.razor")]
public void UnnecessaryUsings_RazorImportsRazorFile_NoIssueReported(string fileName) =>
builder
.AddSnippet(@"@using System.Text.Json;", fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyNoIssueReported();
builder.AddSnippet(@"@using System.Text.Json;", fileName).VerifyNoIssueReported();

[DataTestMethod]
[DataRow("RandomFile_ViewImports.cshtml")]
[DataRow("RandomFile_Imports.cshtml")]
[DataRow("_Imports.cshtml")]
public void UnnecessaryUsings_RazorViewImportsSimilarCshtmlFile_IssuesReported(string fileName) =>
builder
builder.AddReferences(NuGetMetadataReference.SystemTextJson("7.0.4"))
.AddSnippet("@using System.Linq;", "_ViewImports.cshtml")
.AddSnippet(@"@using System.Text.Json; @* Noncompliant *@", fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();

[DataTestMethod]
[DataRow("RandomFile_ViewImports.razor")]
[DataRow("RandomFile_Imports.razor")]
[DataRow("_ViewImports.razor")]
public void UnnecessaryUsings_RazorViewImportsSimilarRazorFile_IssuesReported(string fileName) =>
builder
.AddSnippet("@using System.Linq;", "_Imports.razor")
.AddSnippet(@"@using System.Text.Json; @* Noncompliant *@", fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.Verify();
builder.AddReferences(NuGetMetadataReference.SystemTextJson("7.0.4"))
.AddSnippet("@using System.Linq;", "_Imports.razor")
.AddSnippet(@"@using System.Text.Json; @* Noncompliant *@", fileName)
.Verify();

[DataTestMethod]
[DataRow("_ViewImports.cs")]
Expand Down
Expand Up @@ -90,7 +90,6 @@ public class CopyPasteTokenAnalyzerTest
[TestMethod]
public void Verify_Duplicated_CS_GlobalUsings() =>
CreateBuilder(ProjectType.Product, "Duplicated.CSharp10.cs")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<CopyPasteTokenInfo>(messages =>
{
messages.Should().ContainSingle();
Expand Down Expand Up @@ -122,7 +121,6 @@ public class CopyPasteTokenAnalyzerTest

private void Verify(string fileName, Action<IReadOnlyList<CopyPasteTokenInfo.Types.TokenInfo>> verifyTokenInfo) =>
CreateBuilder(ProjectType.Product, fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<CopyPasteTokenInfo>(messages =>
{
messages.Should().ContainSingle();
Expand All @@ -138,8 +136,9 @@ public class CopyPasteTokenAnalyzerTest
[DataRow("Razor.cshtml")]
public void Verify_NoMetricsAreComputedForRazorFiles(string fileName) =>
CreateBuilder(ProjectType.Product, fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<CopyPasteTokenInfo>(messages => messages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEmpty());
.VerifyUtilityAnalyzer<CopyPasteTokenInfo>(messages => messages.Select(x => Path.GetFileName(x.FilePath))
.Should()
.BeEmpty());

#endif

Expand Down
Expand Up @@ -106,13 +106,12 @@ public void CreateMessage_NoEncoding_SetsEmptyString(bool isTestProject)
#if NET

[DataTestMethod]
[DataRow("Razor.razor", "EmptyProject.GlobalUsings.g.cs", ".NETCoreApp,Version=v7.0.AssemblyAttributes.cs", "EmptyProject.AssemblyInfo.cs")]
[DataRow("Razor.cshtml", "EmptyProject.GlobalUsings.g.cs", ".NETCoreApp,Version=v7.0.AssemblyAttributes.cs", "EmptyProject.AssemblyInfo.cs", "EmptyProject.RazorAssemblyInfo.cs")]
public void Verify_RazorFilesAreIgnored(string fileName, params string[] expectedFiles) =>
[DataRow("Razor.razor")]
[DataRow("Razor.cshtml")]
public void Verify_RazorFilesAreIgnored(string fileName) =>
CreateBuilder(ProjectType.Product, fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<FileMetadataInfo>(messages =>
messages.Select(x => Path.GetFileName(x.FilePath)).Should().Contain(expectedFiles)); // There are more files on some PCs: JSExports.g.cs, LibraryImports.g.cs, JSImports.g.cs
messages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEmpty()); // There are more files on some PCs: JSExports.g.cs, LibraryImports.g.cs, JSImports.g.cs

#endif

Expand Down
Expand Up @@ -63,14 +63,12 @@ public void LogAutogenerated_CsHtml()
{
const string fileName = "Generated_cshtml.g.cs";
CreateBuilder(fileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<LogInfo>(logs => logs.Should().NotContain(x => x.Text.IndexOf(fileName, StringComparison.OrdinalIgnoreCase) != -1));
}

[TestMethod]
public void LogAutogenerated_Razor() =>
CreateBuilder("Generated_razor.g.cs")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<LogInfo>(logs => logs.Select(x => x.Text).Should().Contain($"File 'Utilities\\LogAnalyzer\\Generated_razor.g.cs' was recognized as razor generated"));

[DataTestMethod]
Expand All @@ -82,9 +80,7 @@ public void LogAutogenerated_CsHtml()
.VerifyUtilityAnalyzer<LogInfo>(x => x.Where(info => info.Text.Contains("generated")).Should().HaveCount(expectedGeneratedFiles));

private void Verify(string[] paths, Action<IReadOnlyList<LogInfo>> verifyProtobuf) =>
CreateBuilder(paths)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer(verifyProtobuf);
CreateBuilder(paths).VerifyUtilityAnalyzer(verifyProtobuf);

private VerifierBuilder CreateBuilder(params string[] paths)
{
Expand Down
Expand Up @@ -40,7 +40,6 @@ public class MetricsAnalyzerTest
[DataTestMethod]
public void VerifyMetrics() =>
CreateBuilder(false, AllMetricsFileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<MetricsInfo>(messages =>
{
messages.Should().ContainSingle();
Expand All @@ -62,11 +61,10 @@ public class MetricsAnalyzerTest
[TestMethod]
public void VerifyMetrics_Razor() =>
CreateBuilder(false, RazorFileName, "Component.razor")
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<MetricsInfo>(messages =>
{
var orderedMessages = messages.OrderBy(x => x.FilePath, StringComparer.InvariantCulture).ToArray();
orderedMessages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEquivalentTo("_Imports.razor", RazorFileName, "Component.razor");
orderedMessages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEquivalentTo(RazorFileName, "Component.razor");

var metrics = messages.Single(x => x.FilePath.EndsWith(RazorFileName));

Expand All @@ -84,15 +82,13 @@ public class MetricsAnalyzerTest
[TestMethod]
public void VerifyMetrics_CsHtml() =>
CreateBuilder(false, CsHtmlFileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<MetricsInfo>(messages =>
// There should be no metrics messages for the cshtml files.
messages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEquivalentTo("_Imports.razor"));
messages.Select(x => Path.GetFileName(x.FilePath)).Should().BeEmpty());

[TestMethod]
public void VerifyMetrics_CSharp12() =>
CreateBuilder(false, CSharp12FileName)
.WithAdditionalFilePath(AnalysisScaffolding.CreateSonarProjectConfig(TestContext, ProjectType.Product))
.VerifyUtilityAnalyzer<MetricsInfo>(messages =>
{
messages.Should().ContainSingle();
Expand Down