An open API service indexing awesome lists of open source software.

https://github.com/verifytests/verify.sourcegenerators

Extends Verify to allow verification of C# Source Generators.
https://github.com/verifytests/verify.sourcegenerators

Last synced: about 1 year ago
JSON representation

Extends Verify to allow verification of C# Source Generators.

Awesome Lists containing this project

README

          

# Verify.SourceGenerators

[![Discussions](https://img.shields.io/badge/Verify-Discussions-yellow?svg=true&label=)](https://github.com/orgs/VerifyTests/discussions)
[![Build status](https://ci.appveyor.com/api/projects/status/2ip7do6jk0gevt0v?svg=true)](https://ci.appveyor.com/project/SimonCropp/Verify-SourceGenerators)
[![NuGet Status](https://img.shields.io/nuget/v/Verify.SourceGenerators.svg)](https://www.nuget.org/packages/Verify.SourceGenerators/)

Extends [Verify](https://github.com/VerifyTests/Verify) to allow verification of C# Source Generators.

**See [Milestones](../../milestones?state=closed) for release notes.**

## NuGet package

https://nuget.org/packages/Verify.SourceGenerators/

Install one of the Verify [testing framework adapters](https://github.com/verifytests/verify#nuget-packages) NuGet packages.

## Initialize


```cs
[ModuleInitializer]
public static void Init() =>
VerifySourceGenerators.Initialize();
```
snippet source | anchor

## Generator

Given a Source Generator:


```cs
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

[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)
{
}
}
```
snippet source | anchor

## Test

Can be tested as follows:

This snippets assumes use of the XUnit Verify adapter, change the `using VerifyXUnit` if using other testing frameworks.


```cs
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);
}
}
```
snippet source | anchor

## Results

And will result in the following verified files:

### Info file

An info file containing all metadata about the current state. eg any Diagnostics.


```txt
{
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
}
}
]
}
```
snippet source | anchor

### Source Files

Multiple source files. One for each `GeneratorDriverRunResult.Results.GeneratedSources`.


```cs
//HintName: helloWorld.cs
using System;
public static class HelloWorld
{
public static void SayHello()
{
Console.WriteLine("Hello from generated code!");
}
}
```
snippet source | anchor

## Manipulating Source

To manipulating the source of the generated cs files, use [Scrubbers](https://github.com/VerifyTests/Verify/blob/main/docs/scrubbers.md).

For example to remove all lines start with `using`:


```cs
[Fact]
public Task ScrubLines()
{
var driver = GeneratorDriver();

return Verify(driver)
.ScrubLines(_ => _.StartsWith("using "));
}
```
snippet source | anchor

## Ignoring Files

To ignore specific source text use `IgnoreGeneratedResult`. This uses an expression of type `Func` to determine which outputs are ignored.

For example to ignore files with the name `helper` or that contain the text `static void SayHello()`:


```cs
[Fact]
public Task IgnoreFile()
{
var driver = GeneratorDriver();

return Verify(driver)
.IgnoreGeneratedResult(
_ => _.HintName.Contains("helper") ||
_.SourceText
.ToString()
.Contains("static void SayHello()"));
}
```
snippet source | anchor

## Notes:

* [Source Generators Cookbook / Testing](https://github.com/dotnet/roslyn/blob/main/docs/features/source-generators.cookbook.md#unit-testing-of-generators)

## Icon

[Sauce](https://thenounproject.com/term/sauce/952995/) designed by [April Hsuan](https://thenounproject.com/AprilHsuan/) from [The Noun Project](https://thenounproject.com/).