بررسی Source Generators در #C - قسمت پنجم - نوشتن آزمونهای واحد
نویسنده: وحید نصیری
تاریخ: ۱۴۰۱/۰۵/۲۱ ۱۰:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NotifyPropertyChangedGenerator\NotifyPropertyChangedGenerator.csproj" />
</ItemGroup>
</Project> internal static class SourceGeneratorTestsExtensions
{
public static (GeneratorDriver Driver, Compilation OutputCompilation, ImmutableArray<Diagnostic> Diagnostics)
RunGenerators(this string source, params ISourceGenerator[] generators)
{
var references =
AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly => !assembly.IsDynamic)
.Select(assembly => MetadataReference.CreateFromFile(assembly.Location))
.Cast<MetadataReference>();
var inputCompilation = CSharpCompilation.Create("compilation",
new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Latest)) },
references,
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
GeneratorDriver driver = CSharpGeneratorDriver.Create(generators);
driver = driver.RunGeneratorsAndUpdateCompilation(
inputCompilation,
out var outputCompilation,
out var diagnostics);
return (driver, outputCompilation, diagnostics);
}
} using Microsoft.VisualStudio.TestTools.UnitTesting;
using PropertyChangedGenerator = NotifyPropertyChangedGenerator.NotifyPropertyChangedGenerator;
namespace NotifyPropertyChangedGenerator.Tests;
[TestClass]
public class GeneratorTest
{
[TestMethod]
public void SimpleGeneratorTest()
{
var userSource = @"
using System;
using System.ComponentModel;
namespace NotifyPropertyChangedDemo
{
public class Test : INotifyPropertyChanged
{
private int regularField;
private int IndexBackingField;
}
}
";
var (driver, outputCompilation, diagnostics) =
userSource.RunGenerators(new PropertyChangedGenerator());
var newFile = outputCompilation.SyntaxTrees
.Single(x => Path.GetFileName(x.FilePath).EndsWith(".Test.cs"));
Assert.IsNotNull(newFile);
Assert.IsTrue(newFile.FilePath.EndsWith("Test.Notify.Test.cs"));
var generatedSource = newFile.GetText().ToString();
Assert.IsTrue(generatedSource.Contains("namespace NotifyPropertyChangedDemo"));
// We can now assert things about the resulting compilation:
Assert.IsTrue(diagnostics.IsEmpty); // there were no diagnostics created by the generators
// we have two syntax trees, the original 'user' provided one, and the one added by the generator
Assert.IsTrue(outputCompilation.SyntaxTrees.Count() == 2);
// verify the compilation with the added source has no diagnostics
Assert.IsTrue(outputCompilation.GetDiagnostics().IsEmpty);
}
} public class WeatherForecastController : ControllerBase
Assert.IsTrue(outputCompilation.GetDiagnostics().IsEmpty)
references = references.Concat(new[]
{
MetadataReference.CreateFromFile(typeof(ControllerBase).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(typeof(IActionResult).GetTypeInfo().Assembly.Location)
}); <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>
</Project> new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)