Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored SampleGen test tooling #69

Merged
merged 20 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f37635a
Created ToolkitSampleButtonActionAttribute, general cleanup
Arlodotexe Mar 28, 2023
9da7b05
WIP adding method support to SampleGen
Arlodotexe Mar 31, 2023
c42c1fd
Cleaning up and organizing SampleGen test tooling
Arlodotexe Apr 1, 2023
7cb2ce7
Complete refactor of SampleGen tests
Arlodotexe Apr 4, 2023
0e7616d
Refactored test tooling for additional flexibility
Arlodotexe Apr 5, 2023
b8481d1
Updated tooling and refactored SampleGen to remove special code path …
Arlodotexe Apr 5, 2023
c698a4b
Enabled asserting partial string comparisons of generated source.
Arlodotexe Apr 5, 2023
08914e7
Fixes to accomodate generated ToolkitSampleButtonAction
Arlodotexe Apr 6, 2023
96a460f
Fixed not finding attributes on methods symbols, misc cleanup
Arlodotexe Apr 11, 2023
f8c94e3
Minor cleanup
Arlodotexe Apr 11, 2023
cc95e34
Merge
Arlodotexe Jun 6, 2023
d063715
Checkpoint commit
Arlodotexe Jun 15, 2023
102f46a
Removed generated ButtonAction sample pane option
Arlodotexe Jun 15, 2023
f56854a
Ran XAML styler
Arlodotexe Jun 15, 2023
8d5e5d2
Use .NET 7 for global json version
Arlodotexe Jun 15, 2023
cc00f93
Move to C# 11 string literals
Arlodotexe Jun 28, 2023
4b581d1
Fix syntax in string literals
Arlodotexe Jun 28, 2023
9138346
Update CommunityToolkit.Tooling.SampleGen/ToolkitSampleOptionGenerato…
Arlodotexe Jun 28, 2023
d1307a5
Update CommunityToolkit.Tooling.SampleGen/ToolkitSampleMetadataGenera…
Arlodotexe Jun 28, 2023
f53878b
Fixed build errors from review sugestion
Arlodotexe Jun 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
workflow_dispatch:

env:
DOTNET_VERSION: ${{ '6.0.x' }}
DOTNET_VERSION: ${{ '7.0.x' }}
ENABLE_DIAGNOSTICS: false
#COREHOST_TRACE: 1
COREHOST_TRACEFILE: corehosttrace.log
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<UserControl x:Class="CommunityToolkit.App.Shared.Renderers.GeneratedSampleOptionsRenderer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

namespace CommunityToolkit.Tooling.SampleGen.Tests.Helpers;

internal class InMemoryAdditionalText : AdditionalText
{
private readonly SourceText _content;

public InMemoryAdditionalText(string path, string content)
{
Path = path;
_content = SourceText.From(content, Encoding.UTF8);
}

public override string Path { get; }

public override SourceText GetText(CancellationToken cancellationToken = default) => _content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis;
using System.Collections.Immutable;

namespace CommunityToolkit.Tooling.SampleGen.Tests.Helpers;

public record SourceGeneratorRunResult(Compilation Compilation, ImmutableArray<Diagnostic> Diagnostics);
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Immutable;

namespace CommunityToolkit.Tooling.SampleGen.Tests.Helpers;

public static partial class TestHelpers
{
internal static IEnumerable<MetadataReference> GetAllReferencedAssemblies()
{
return from assembly in AppDomain.CurrentDomain.GetAssemblies()
where !assembly.IsDynamic
let reference = MetadataReference.CreateFromFile(assembly.Location)
select reference;
}

internal static SyntaxTree ToSyntaxTree(this string source)
{
return CSharpSyntaxTree.ParseText(source,
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10));
}

internal static CSharpCompilation CreateCompilation(this SyntaxTree syntaxTree, string assemblyName, IEnumerable<MetadataReference>? references = null)
{
return CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, references ?? GetAllReferencedAssemblies(), new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
}

internal static CSharpCompilation CreateCompilation(this IEnumerable<SyntaxTree> syntaxTree, string assemblyName, IEnumerable<MetadataReference>? references = null)
{
return CSharpCompilation.Create(assemblyName, syntaxTree, references ?? GetAllReferencedAssemblies(), new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
}

internal static GeneratorDriver CreateSourceGeneratorDriver(this SyntaxTree syntaxTree, params IIncrementalGenerator[] generators)
{
return CSharpGeneratorDriver.Create(generators).WithUpdatedParseOptions((CSharpParseOptions)syntaxTree.Options);
}

internal static GeneratorDriver CreateSourceGeneratorDriver(this Compilation compilation, params IIncrementalGenerator[] generators)
{
return CSharpGeneratorDriver.Create(generators).WithUpdatedParseOptions((CSharpParseOptions)compilation.SyntaxTrees.First().Options);
}

internal static GeneratorDriver WithMarkdown(this GeneratorDriver driver, params string[] markdownFilesToCreate)
{
foreach (var markdown in markdownFilesToCreate)
{
if (!string.IsNullOrWhiteSpace(markdown))
{
var text = new InMemoryAdditionalText(@"C:\pathtorepo\components\experiment\samples\experiment.Samples\documentation.md", markdown);
driver = driver.AddAdditionalTexts(ImmutableArray.Create<AdditionalText>(text));
}
}

return driver;
}
}
61 changes: 61 additions & 0 deletions CommunityToolkit.Tooling.SampleGen.Tests/Helpers/TestHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Immutable;

namespace CommunityToolkit.Tooling.SampleGen.Tests.Helpers;

public static partial class TestHelpers
{
internal static SourceGeneratorRunResult RunSourceGenerator<TGenerator>(this string source, string assemblyName, string markdown = "") where TGenerator : class, IIncrementalGenerator, new() => RunSourceGenerator<TGenerator>(source.ToSyntaxTree(), assemblyName, markdown);

internal static SourceGeneratorRunResult RunSourceGenerator<TGenerator>(this SyntaxTree syntaxTree, string assemblyName, string markdown = "")
where TGenerator : class, IIncrementalGenerator, new()
{
var compilation = syntaxTree.CreateCompilation(assemblyName); // assembly name should always be supplied in param
return RunSourceGenerator<TGenerator>(compilation, markdown);
}

internal static SourceGeneratorRunResult RunSourceGenerator<TGenerator>(this Compilation compilation, string markdown = "")
where TGenerator : class, IIncrementalGenerator, new()
{
// Create a driver for the source generator
var driver = compilation
.CreateSourceGeneratorDriver(new TGenerator())
.WithMarkdown(markdown);

// Update the original compilation using the source generator
_ = driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation generatorCompilation, out ImmutableArray<Diagnostic> postGeneratorCompilationDiagnostics);

return new(generatorCompilation, postGeneratorCompilationDiagnostics);
}

internal static void AssertDiagnosticsAre(this IEnumerable<Diagnostic> diagnostics, params DiagnosticDescriptor[] expectedDiagnosticDescriptors)
{
var expectedIds = expectedDiagnosticDescriptors.Select(x => x.Id).ToHashSet();
var resultingIds = diagnostics.Select(diagnostic => diagnostic.Id).ToHashSet();

Assert.IsTrue(resultingIds.SetEquals(expectedIds), $"Expected [{string.Join(", ", expectedIds)}] diagnostic Ids. Got [{string.Join(", ", resultingIds)}]");
}

internal static void AssertNoCompilationErrors(this Compilation outputCompilation)
{
var generatedCompilationDiagnostics = outputCompilation.GetDiagnostics();
Assert.IsTrue(generatedCompilationDiagnostics.All(x => x.Severity != DiagnosticSeverity.Error), $"Expected no generated compilation errors. Got: \n{string.Join("\n", generatedCompilationDiagnostics.Where(x => x.Severity == DiagnosticSeverity.Error).Select(x => $"[{x.Id}: {x.GetMessage()}]"))}");
}

internal static string GetFileContentsByName(this Compilation compilation, string filename)
{
var generatedTree = compilation.SyntaxTrees.SingleOrDefault(tree => Path.GetFileName(tree.FilePath) == filename);
Assert.IsNotNull(generatedTree, $"No file named {filename} was generated");

return generatedTree.ToString();
}

internal static void AssertSourceGenerated(this Compilation compilation, string filename, string expectedContents)
{
}

internal static void AssertDiagnosticsAre(this SourceGeneratorRunResult result, params DiagnosticDescriptor[] expectedDiagnosticDescriptors) => AssertDiagnosticsAre(result.Diagnostics, expectedDiagnosticDescriptors);

internal static void AssertNoCompilationErrors(this SourceGeneratorRunResult result) => AssertNoCompilationErrors(result.Compilation);
}
Loading