-
Notifications
You must be signed in to change notification settings - Fork 73
Added [LabsUITestMethod] attribute and source generator #156
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
Merged
Merged
Changes from 5 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
ef4ea44
Created UIControlTestMethod generator + unit tests
Arlodotexe 48e1d81
Added new source generators to template
Arlodotexe 6f69e44
Migrated existing tests to new source generator attribute
Arlodotexe 65824ce
Refactored to pull control instance directly from method params. Impr…
Arlodotexe e8222b5
Cleanup outdated comments
Arlodotexe 2eaaa31
Added mandatory content cleanup for UI tests
Arlodotexe b8cafae
Fixed diagnostic ID to match project name initials
Arlodotexe 1e386dc
Fixed source generator to only check public constructors for LUITM0001
Arlodotexe d73a60a
Fixed test setup/cleanup invoking on the wrong thread
Arlodotexe 0d69c75
Added new source generator to individual project solutions
Arlodotexe 7973bfd
Reverted to toolkit extension for dispatcher EnqueueAsync
Arlodotexe 2cd1c95
Remove whitespace
Arlodotexe 2b9c194
Merge from main
Arlodotexe cc33331
Fixed non file-scoped namespaces
Arlodotexe 1fc7250
Added missing file header
Arlodotexe 9b6d524
Removed unused using directives
Arlodotexe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
...estMethod.Tests/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod\CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
297 changes: 297 additions & 0 deletions
297
...mmunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Tests/LabsUITestMethodTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Diagnostics; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
|
||
namespace CommunityToolkit.Labs.Core.SourceGenerators.Tests | ||
Arlodotexe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
[TestClass] | ||
public partial class LabsUITestMethodTests | ||
Arlodotexe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
private const string DispatcherQueueDefinition = @" | ||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task EnqueueAsync<T>(System.Func<System.Threading.Tasks.Task<T>> function) => System.Threading.Tasks.Task.Run(function); | ||
|
||
public System.Threading.Tasks.Task EnqueueAsync(System.Action function) => System.Threading.Tasks.Task.Run(function); | ||
} | ||
} | ||
"; | ||
|
||
[TestMethod] | ||
public void TestControlHasConstructorWithParameters() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task LoadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
public System.Threading.Tasks.Task UnloadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
|
||
[LabsUITestMethod] | ||
public void TestMethod(MyControl control) | ||
{ | ||
} | ||
} | ||
|
||
public class MyControl : Microsoft.UI.Xaml.FrameworkElement | ||
{ | ||
public MyControl(string id) | ||
{ | ||
} | ||
} | ||
} | ||
|
||
namespace Microsoft.UI.Xaml | ||
{ | ||
public class FrameworkElement { } | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition, DiagnosticDescriptors.TestControlHasConstructorWithParameters.Id); | ||
} | ||
|
||
[TestMethod] | ||
public void Async_Mux_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task LoadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
public System.Threading.Tasks.Task UnloadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
|
||
[LabsUITestMethod] | ||
public async System.Threading.Tasks.Task TestMethod(MyControl control) | ||
{ | ||
} | ||
} | ||
|
||
public class MyControl : Microsoft.UI.Xaml.FrameworkElement | ||
{ | ||
} | ||
} | ||
|
||
namespace Microsoft.UI.Xaml | ||
{ | ||
public class FrameworkElement { } | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
[TestMethod] | ||
public void Async_Wux_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task LoadTestContentAsync(Windows.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
public System.Threading.Tasks.Task UnloadTestContentAsync(Windows.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
|
||
[LabsUITestMethod] | ||
public async System.Threading.Tasks.Task TestMethod(MyControl control) | ||
{ | ||
} | ||
} | ||
|
||
public class MyControl : Windows.UI.Xaml.FrameworkElement | ||
{ | ||
} | ||
} | ||
|
||
namespace Windows.UI.Xaml | ||
{ | ||
public class FrameworkElement { } | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
[TestMethod] | ||
public void Async_NoMethodParams_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
[LabsUITestMethod] | ||
public async System.Threading.Tasks.Task TestMethod() | ||
{ | ||
} | ||
} | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
[TestMethod] | ||
public void Synchronous_Mux_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task LoadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
public System.Threading.Tasks.Task UnloadTestContentAsync(Microsoft.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
|
||
[LabsUITestMethod] | ||
public void TestMethod(MyControl control) | ||
{ | ||
} | ||
} | ||
|
||
public class MyControl : Microsoft.UI.Xaml.FrameworkElement | ||
{ | ||
} | ||
} | ||
|
||
namespace Microsoft.UI.Xaml | ||
{ | ||
public class FrameworkElement { } | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
[TestMethod] | ||
public void Synchronous_Wux_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
public System.Threading.Tasks.Task LoadTestContentAsync(Windows.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
public System.Threading.Tasks.Task UnloadTestContentAsync(Windows.UI.Xaml.FrameworkElement content) => System.Threading.Tasks.Task.CompletedTask; | ||
|
||
[LabsUITestMethod] | ||
public void TestMethod(MyControl control) | ||
{ | ||
} | ||
} | ||
|
||
public class MyControl : Windows.UI.Xaml.FrameworkElement | ||
{ | ||
} | ||
} | ||
|
||
namespace Windows.UI.Xaml | ||
{ | ||
public class FrameworkElement { } | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
[TestMethod] | ||
public void Synchronous_NoMethodParams_NoErrors() | ||
{ | ||
string source = @" | ||
using System.ComponentModel; | ||
using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod; | ||
|
||
namespace MyApp | ||
{ | ||
public partial class Test | ||
{ | ||
[LabsUITestMethod] | ||
public void TestMethod() | ||
{ | ||
} | ||
} | ||
}"; | ||
|
||
VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition); | ||
} | ||
|
||
/// <summary> | ||
/// Verifies the output of a source generator. | ||
/// </summary> | ||
/// <typeparam name="TGenerator">The generator type to use.</typeparam> | ||
/// <param name="source">The input source to process.</param> | ||
/// <param name="markdown">The input documentation info to process.</param> | ||
/// <param name="diagnosticsIds">The diagnostic ids to expect for the input source code.</param> | ||
private static void VerifyGeneratedDiagnostics<TGenerator>(string source, params string[] diagnosticsIds) | ||
where TGenerator : class, IIncrementalGenerator, new() | ||
{ | ||
VerifyGeneratedDiagnostics<TGenerator>(CSharpSyntaxTree.ParseText(source), diagnosticsIds); | ||
} | ||
|
||
/// <summary> | ||
/// Verifies the output of a source generator. | ||
/// </summary> | ||
/// <typeparam name="TGenerator">The generator type to use.</typeparam> | ||
/// <param name="syntaxTree">The input source tree to process.</param> | ||
/// <param name="markdown">The input documentation info to process.</param> | ||
/// <param name="diagnosticsIds">The diagnostic ids to expect for the input source code.</param> | ||
private static void VerifyGeneratedDiagnostics<TGenerator>(SyntaxTree syntaxTree, params string[] diagnosticsIds) | ||
where TGenerator : class, IIncrementalGenerator, new() | ||
{ | ||
var attributeType = typeof(LabsUITestMethodAttribute); | ||
|
||
var references = | ||
from assembly in AppDomain.CurrentDomain.GetAssemblies() | ||
where !assembly.IsDynamic | ||
let reference = MetadataReference.CreateFromFile(assembly.Location) | ||
select reference; | ||
|
||
var compilation = CSharpCompilation.Create( | ||
"original.Sample", | ||
new[] { syntaxTree }, | ||
references, | ||
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); | ||
|
||
var compilationDiagnostics = compilation.GetDiagnostics(); | ||
|
||
Assert.IsTrue(compilationDiagnostics.All(x => x.Severity != DiagnosticSeverity.Error), $"Expected no compilation errors before source generation. Got: \n{string.Join("\n", compilationDiagnostics.Where(x => x.Severity == DiagnosticSeverity.Error).Select(x => $"[{x.Id}: {x.GetMessage()}]"))}"); | ||
|
||
IIncrementalGenerator generator = new TGenerator(); | ||
|
||
GeneratorDriver driver = | ||
CSharpGeneratorDriver | ||
.Create(generator) | ||
.WithUpdatedParseOptions((CSharpParseOptions)syntaxTree.Options); | ||
|
||
_ = driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation outputCompilation, out ImmutableArray<Diagnostic> diagnostics); | ||
|
||
HashSet<string> resultingIds = diagnostics.Select(diagnostic => diagnostic.Id).ToHashSet(); | ||
var generatedCompilationDiaghostics = outputCompilation.GetDiagnostics(); | ||
|
||
Assert.IsTrue(resultingIds.SetEquals(diagnosticsIds), $"Expected one of [{string.Join(", ", diagnosticsIds)}] diagnostic Ids. Got [{string.Join(", ", resultingIds)}]"); | ||
Assert.IsTrue(generatedCompilationDiaghostics.All(x => x.Severity != DiagnosticSeverity.Error), $"Expected no generated compilation errors. Got: \n{string.Join("\n", generatedCompilationDiaghostics.Where(x => x.Severity == DiagnosticSeverity.Error).Select(x => $"[{x.Id}: {x.GetMessage()}]"))}"); | ||
|
||
GC.KeepAlive(attributeType); | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...tors.LabsUITestMethod/CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<WarningsAsErrors>nullable</WarningsAsErrors> | ||
<LangVersion>10.0</LangVersion> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" /> | ||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" /> | ||
</ItemGroup> | ||
</Project> |
29 changes: 29 additions & 0 deletions
29
...yToolkit.Labs.Core.SourceGenerators.LabsUITestMethod/Diagnostics/DiagnosticDescriptors.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// 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; | ||
|
||
namespace CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod.Diagnostics | ||
Arlodotexe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
/// <summary> | ||
/// A container for all <see cref="DiagnosticDescriptor"/> instances for errors reported by analyzers in this project. | ||
/// </summary> | ||
public static class DiagnosticDescriptors | ||
{ | ||
/// <summary> | ||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating that a test method decorated with <see cref="LabsUITestMethodAttribute"/> asks for a control instance with a non-parameterless constructor. | ||
/// <para> | ||
/// Format: <c>"Cannot generate test with type {0} as it has a constructor with parameters."</c>. | ||
/// </para> | ||
/// </summary> | ||
public static readonly DiagnosticDescriptor TestControlHasConstructorWithParameters = new( | ||
id: "UICTRLTM0001", | ||
title: $"Provided control must not have a constructor with parameters.", | ||
messageFormat: $"Cannot generate test with control {{0}} as it has a constructor with parameters.", | ||
category: typeof(LabsUITestMethodGenerator).FullName, | ||
defaultSeverity: DiagnosticSeverity.Error, | ||
isEnabledByDefault: true, | ||
description: $"Cannot generate test method with provided control."); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.