Skip to content

Commit

Permalink
Merge pull request #10 from DeNA/feature/extraMetaData
Browse files Browse the repository at this point in the history
Feature: Dena.CodeAnalysis.Testing can read metadata.
  • Loading branch information
Kuniwak authored Jan 30, 2024
2 parents 1de96c5 + 3852aea commit b7e63e6
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 29 deletions.
27 changes: 20 additions & 7 deletions src/Dena.CodeAnalysis.Testing/AnalyzerRunner.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
Expand All @@ -12,7 +13,6 @@
using Microsoft.VisualStudio.Composition;



namespace Dena.CodeAnalysis.CSharp.Testing
{
/// <summary>
Expand All @@ -31,22 +31,24 @@ public static class DiagnosticAnalyzerRunner
/// Run the specified <see cref="DiagnosticAnalyzer" />.
/// </summary>
/// <param name="analyzer">The <see cref="DiagnosticAnalyzer" /> to run.</param>
/// <param name="types">The type of metadata you want to add.</param>
/// <param name="codes">The target code that the <paramref name="analyzer" /> analyze.</param>
/// <returns>ImmutableArray contains all reported <see cref="Diagnostic" />.</returns>
/// <throws>Throws <c cref="AtLeastOneCodeMustBeRequired" /> if <paramref name="codes" /> are empty.</throws>
public static async Task<ImmutableArray<Diagnostic>> Run(
DiagnosticAnalyzer analyzer,
Type[] types = default,
params string[] codes
) =>
await Run(
analyzer,
CancellationToken.None,
ParseOptionsForLanguageVersionsDefault(),
CompilationOptionsForDynamicClassLibrary(),
MetadataReferencesDefault(types),
codes
);


/// <summary>
/// Run the specified <see cref="DiagnosticAnalyzer" />.
/// </summary>
Expand All @@ -63,6 +65,7 @@ public static async Task<ImmutableArray<Diagnostic>> Run(
CancellationToken cancellationToken,
ParseOptions parseOptions,
CompilationOptions compilationOptions,
IEnumerable<MetadataReference> metadataReferences,
params string[] codes
)
{
Expand All @@ -89,10 +92,6 @@ params string[] codes

var noMetadataReferencedProject = solution.Projects.First();

// NOTE: Make .NET standard libraries visible to the specified codes to analyze.
var metadataReferences =
await ReferenceAssemblies.Default.ResolveAsync(Language, CancellationToken.None);

var project = noMetadataReferencedProject
.AddMetadataReferences(metadataReferences)
.WithParseOptions(parseOptions)
Expand Down Expand Up @@ -120,6 +119,21 @@ public static CompilationOptions CompilationOptionsForDynamicClassLibrary() =>
public static ParseOptions ParseOptionsForLanguageVersionsDefault() =>
new CSharpParseOptions(DefaultLanguageVersion, DocumentationMode.Diagnose);

private static IEnumerable<MetadataReference> MetadataReferencesDefault(Type[] types)
{
var metadataReferences = ReferenceAssemblies.Default.ResolveAsync(Language, CancellationToken.None).Result
.ToList();
if (types != null)
{
foreach (var type in types)
{
metadataReferences.Add(MetadataReference.CreateFromFile(type.Assembly.Location));
}
}

return metadataReferences;
}


/// <summary>
/// This value is equivalent to <see cref="Microsoft.CodeAnalysis.Testing.AnalyzerTest{IVerifier}.DefaultFilePathPrefix" />
Expand Down Expand Up @@ -191,7 +205,6 @@ static DiagnosticAnalyzerRunner()
}



/// <summary>
/// None of codes specified but at least one code must be required.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/Dena.CodeAnalysis.Testing/ExampleCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ internal static void Bar()
}
";

public const string UniTaskImport = @"
using Cysharp.Threading.Tasks;
internal static class Foo
{
internal static void Bar()
{
System.Console.WriteLine(""Hello, World!"");
}
}";

/// <summary>
/// An example code that contains a syntax error.
/// </summary>
Expand Down
19 changes: 16 additions & 3 deletions tests/Dena.CodeAnalysis.Testing.Tests/AnalyzerRunnerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MSTestAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;

Expand All @@ -25,20 +26,32 @@ public async Task WhenGivenDiagnosticCleanCode_ItShouldReturnNoDiagnostics()
var anyAnalyzer = new NullAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(
anyAnalyzer,
ExampleCode.DiagnosticsFreeClassLibrary
codes: ExampleCode.DiagnosticsFreeClassLibrary
);

MSTestAssert.AreEqual(0, diagnostics.Length, DiagnosticsFormatter.Format(diagnostics));
}

[TestMethod]
public async Task WhenGivenUniTaskImport_ItShouldReturnNoDiagnostics()
{
var anyAnalyzer = new NullAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(
anyAnalyzer,
new[] { typeof(UniTask) },
ExampleCode.UniTaskImport
);

MSTestAssert.AreEqual(1, diagnostics.Length, DiagnosticsFormatter.Format(diagnostics));
}

[TestMethod]
public async Task WhenGivenContainingASyntaxError_ItShouldReturnSeveralDiagnostics()
{
var anyAnalyzer = new NullAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(
anyAnalyzer,
ExampleCode.ContainingSyntaxError
codes: ExampleCode.ContainingSyntaxError
);

MSTestAssert.AreNotEqual(0, diagnostics.Length);
Expand All @@ -50,7 +63,7 @@ public async Task WhenGivenAnyCodes_ItShouldCallAnalyzerInitialize()
{
var spyAnalyzer = new SpyAnalyzer();

await DiagnosticAnalyzerRunner.Run(spyAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(spyAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.IsTrue(spyAnalyzer.IsInitialized);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="UniTask" Version="2.3.3" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using MSTestAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;



namespace Dena.CodeAnalysis.CSharp.Testing
{
[TestClass]
Expand All @@ -14,7 +13,7 @@ public async Task Format()
{
var diagnostics = await DiagnosticAnalyzerRunner.Run(
new NullAnalyzer(),
ExampleCode.ContainingSyntaxError
codes: ExampleCode.ContainingSyntaxError
);

var actual = DiagnosticsFormatter.Format(diagnostics);
Expand Down
2 changes: 1 addition & 1 deletion tests/Dena.CodeAnalysis.Testing.Tests/LocationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static async Task<Location> Create()
{
var ds = await DiagnosticAnalyzerRunner.Run(
new NullAnalyzer(),
ExampleCode.ContainingSyntaxError
codes: ExampleCode.ContainingSyntaxError
);
return ds[0].Location;
}
Expand Down
3 changes: 1 addition & 2 deletions tests/Dena.CodeAnalysis.Testing.Tests/SpyAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using MSTestAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;



namespace Dena.CodeAnalysis.CSharp.Testing
{
[TestClass]
Expand All @@ -17,7 +16,7 @@ public async Task WhenGivenAnyCodes_RecordAllActionHistory()
var builder = new StringBuilder();
var failed = false;

await DiagnosticAnalyzerRunner.Run(spy, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(spy, codes: ExampleCode.DiagnosticsFreeClassLibrary);

if (0 == spy.CodeBlockActionHistory.Count)
{
Expand Down
25 changes: 12 additions & 13 deletions tests/Dena.CodeAnalysis.Testing.Tests/StubAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using MSTestAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;



namespace Dena.CodeAnalysis.CSharp.Testing
{
[TestClass]
Expand All @@ -20,7 +19,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallCodeBlockAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -37,7 +36,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallCodeBlockStartAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -54,7 +53,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallCompilationAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -71,7 +70,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallCompilationStartAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -88,7 +87,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallOperationAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -105,7 +104,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallOperationBlockAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -122,7 +121,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallOperationBlockStartAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -139,7 +138,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallSemanticModelAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -156,7 +155,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallSymbolAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -173,7 +172,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallSymbolStartAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -190,7 +189,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallSyntaxNodeAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand All @@ -207,7 +206,7 @@ public async Task WhenGivenAnyCodes_ItShouldGetToCallSyntaxTreeAction()
}
);

await DiagnosticAnalyzerRunner.Run(stubAnalyzer, ExampleCode.DiagnosticsFreeClassLibrary);
await DiagnosticAnalyzerRunner.Run(stubAnalyzer, codes: ExampleCode.DiagnosticsFreeClassLibrary);

MSTestAssert.AreNotEqual(0, callCount);
}
Expand Down

0 comments on commit b7e63e6

Please sign in to comment.