Extends Verify to allow verification of C# Source Generators.
See Milestones for release notes.
Sponsors
Entity Framework Extensions
Entity Framework Extensions is a major sponsor and is proud to contribute to the development this project.
Developed using JetBrains IDEs
NuGet
Initialize
[ModuleInitializer] public static void Init() => VerifySourceGenerators.Initialize();
Generator
Given a Source Generator:
[Generator] public class HelloWorldGenerator : ISourceGenerator { public void Execute(GeneratorExecutionContext context) { var source1 = """ using System; public static class Helper { public static void Method() { } } """; context.AddSource("helper", SourceText.From(source1, Encoding.UTF8)); var source2 = """ using System; public static class HelloWorld { public static void SayHello() { Console.WriteLine("Hello from generated code!"); } } """; var sourceText = SourceText.From(source2, Encoding.UTF8); context.AddSource("helloWorld", sourceText); var descriptor = new DiagnosticDescriptor( id: "theId", title: "the title", messageFormat: "the message from {0}", category: "the category", DiagnosticSeverity.Info, isEnabledByDefault: true); var location = Location.Create( Path.Combine("dir", "theFile.cs"), new(1, 2), new( new(1, 2), new(3, 4))); var diagnostic = Diagnostic.Create(descriptor, location, "hello world generator"); context.ReportDiagnostic(diagnostic); } public void Initialize(GeneratorInitializationContext context) { } }
Test
Can be tested as follows:
This snippets assumes use of the XUnit Verify adapter, change the using VerifyXUnit if using other testing frameworks.
public class SampleTest { [Fact] public Task Driver() { var driver = BuildDriver(); return Verify(driver); } [Fact] public Task RunResults() { var driver = BuildDriver(); var results = driver.GetRunResult(); return Verify(results); } [Fact] public Task RunResult() { var driver = BuildDriver(); var result = driver.GetRunResult().Results.Single(); return Verify(result); } static GeneratorDriver BuildDriver() { var compilation = CSharpCompilation.Create("name"); var generator = new HelloWorldGenerator(); var driver = CSharpGeneratorDriver.Create(generator); return driver.RunGenerators(compilation); } }
Results
And will result in the following verified files:
Info file
An info file containing all metadata about the current state. eg any Diagnostics.
{
Diagnostics: [
{
Location: dir\theFile.cs: (1,2)-(3,4),
Message: the message from hello world generator,
Severity: Info,
WarningLevel: 1,
Descriptor: {
Id: theId,
Title: the title,
MessageFormat: the message from {0},
Category: the category,
DefaultSeverity: Info,
IsEnabledByDefault: true
}
}
]
}Source Files
Multiple source files. One for each GeneratorDriverRunResult.Results.GeneratedSources.
//HintName: helloWorld.cs using System; public static class HelloWorld { public static void SayHello() { Console.WriteLine("Hello from generated code!"); } }
Manipulating Source
To manipulating the source of the generated cs files, use Scrubbers.
For example to remove all lines start with using:
[Fact] public Task ScrubLines() { var driver = GeneratorDriver(); return Verify(driver) .ScrubLines(_ => _.StartsWith("using ")); }
Ignoring Files
To ignore specific source text use IgnoreGeneratedResult. This uses an expression of type Func<GeneratedSourceResult, bool> to determine which outputs are ignored.
For example to ignore files with the name helper or that contain the text static void SayHello():
[Fact] public Task IgnoreFile() { var driver = GeneratorDriver(); return Verify(driver) .IgnoreGeneratedResult( _ => _.HintName.Contains("helper") || _.SourceText .ToString() .Contains("static void SayHello()")); }
Notes:
Icon
Sauce designed by April Hsuan from The Noun Project.
