Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Framework for unit testing generators
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Xunit;
namespace GeneratorTests.Tests
{
public class GeneratorTests
{
[Fact]
public void SimpleGeneratorTest()
{
string userSource = @"
namespace MyCode
{
public class Program
{
public static void Main(string[] args)
{
}
}
}
";
Compilation comp = CreateCompilation(userSource);
var newComp = RunGenerators(comp, out var generatorDiags, new SimpleGenerator());
Assert.Empty(generatorDiags);
Assert.Empty(newComp.GetDiagnostics());
}
private static Compilation CreateCompilation(string source)
=> CSharpCompilation.Create("compilation",
new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) },
new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) },
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
private static GeneratorDriver CreateDriver(Compilation c, params ISourceGenerator[] generators)
=> new CSharpGeneratorDriver(c.SyntaxTrees.First().Options,
ImmutableArray.Create(generators),
null,
ImmutableArray<AdditionalText>.Empty);
private static Compilation RunGenerators(Compilation c, out ImmutableArray<Diagnostic> diagnostics, params ISourceGenerator[] generators)
{
CreateDriver(c, generators).RunGeneratorsAndUpdateCompilation(c, out var d, out diagnostics);
return d;
}
}
}
@davidwengier

This comment has been minimized.

Copy link

@davidwengier davidwengier commented Aug 15, 2020

Note that due to an API change the CreateDriver method needs to change to:

        private static GeneratorDriver CreateDriver(Compilation c, params ISourceGenerator[] generators)
            => new CSharpGeneratorDriver(c.SyntaxTrees.First().Options,
                ImmutableArray.Create(generators),
                null,
                ImmutableArray<AdditionalText>.Empty);
@chsienki

This comment has been minimized.

Copy link
Owner Author

@chsienki chsienki commented Aug 17, 2020

Updated, thanks @davidwengier

@Youssef1313

This comment has been minimized.

Copy link

@Youssef1313 Youssef1313 commented Sep 25, 2020

Hi @chsienki

GeneratorDriver.RunFullGeneration is now obsolete. It needs to be updated with RunGeneratorsAndUpdateCompilation.

CSharpGeneratorDriver constructor is also obsolete. It needs to be updated with CSharpGeneratorDriver.Create.

Also, ParseOptions will need a cast to CSharpParseOptions.

@cabralRodrigo

This comment has been minimized.

Copy link

@cabralRodrigo cabralRodrigo commented Dec 1, 2020

Is anyone is interested here is a version that works for me (with all the notes above):

private static Compilation CreateCompilation(string source) => CSharpCompilation.Create(
    assemblyName: "compilation",
    syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) },
    references: new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) },
    options: new CSharpCompilationOptions(OutputKind.ConsoleApplication)
);

private static GeneratorDriver CreateDriver(Compilation compilation, params ISourceGenerator[] generators) => CSharpGeneratorDriver.Create(
    generators: ImmutableArray.Create(generators),
    additionalTexts: ImmutableArray<AdditionalText>.Empty,
    parseOptions: (CSharpParseOptions)compilation.SyntaxTrees.First().Options,
    optionsProvider: null
);

private static Compilation RunGenerators(Compilation compilation, out ImmutableArray<Diagnostic> diagnostics, params ISourceGenerator[] generators)
{
    CreateDriver(compilation, generators).RunGeneratorsAndUpdateCompilation(compilation, out var updatedCompilation, out diagnostics);
    return updatedCompilation;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment