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

Add more example test cases to Project Template #189

Merged
merged 5 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,15 @@ namespace Microsoft.UI.Xaml
public class FrameworkElement { }
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsTrue(generatedSource.Contains("await LoadTestContentAsync(testControl);"), "Didn't see expected loading call.");
Assert.IsTrue(generatedSource.Contains("await UnloadTestContentAsync(testControl);"), "Didn't see expected unloading call.");
Assert.IsTrue(generatedSource.Contains("var testControl = new global::MyApp.MyControl();"), "Didn't see expected creation of test control.");
Assert.IsTrue(generatedSource.Contains("await TestMethod(testControl);"), "Didn't see expected running of test.");
}

[TestMethod]
Expand Down Expand Up @@ -124,7 +132,15 @@ namespace Windows.UI.Xaml
public class FrameworkElement { }
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsTrue(generatedSource.Contains("await LoadTestContentAsync(testControl);"), "Didn't see expected loading call.");
Assert.IsTrue(generatedSource.Contains("await UnloadTestContentAsync(testControl);"), "Didn't see expected unloading call.");
Assert.IsTrue(generatedSource.Contains("var testControl = new global::MyApp.MyControl();"), "Didn't see expected creation of test control.");
Assert.IsTrue(generatedSource.Contains("await TestMethod(testControl);"), "Didn't see expected running of test.");
}

[TestMethod]
Expand All @@ -145,7 +161,14 @@ public async System.Threading.Tasks.Task TestMethod()
}
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsFalse(generatedSource.Contains("await LoadTestContentAsync"), "Saw a loading call.");
Assert.IsFalse(generatedSource.Contains("await UnloadTestContentAsync"), "Saw an unloading call.");
Assert.IsTrue(generatedSource.Contains("await TestMethod();"), "Didn't see expected running of test.");
}

[TestMethod]
Expand Down Expand Up @@ -178,7 +201,15 @@ namespace Microsoft.UI.Xaml
public class FrameworkElement { }
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsTrue(generatedSource.Contains("await LoadTestContentAsync(testControl);"), "Didn't see expected loading call.");
Assert.IsTrue(generatedSource.Contains("await UnloadTestContentAsync(testControl);"), "Didn't see expected unloading call.");
Assert.IsTrue(generatedSource.Contains("var testControl = new global::MyApp.MyControl();"), "Didn't see expected creation of test control.");
Assert.IsTrue(generatedSource.Contains("TestMethod(testControl);"), "Didn't see expected running of test.");
}

[TestMethod]
Expand Down Expand Up @@ -211,7 +242,15 @@ namespace Windows.UI.Xaml
public class FrameworkElement { }
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsTrue(generatedSource.Contains("await LoadTestContentAsync(testControl);"), "Didn't see expected loading call.");
Assert.IsTrue(generatedSource.Contains("await UnloadTestContentAsync(testControl);"), "Didn't see expected unloading call.");
Assert.IsTrue(generatedSource.Contains("var testControl = new global::MyApp.MyControl();"), "Didn't see expected creation of test control.");
Assert.IsTrue(generatedSource.Contains("TestMethod(testControl);"), "Didn't see expected running of test.");
}

[TestMethod]
Expand All @@ -232,7 +271,15 @@ public void TestMethod()
}
}";

VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);
var result = VerifyGeneratedDiagnostics<LabsUITestMethodGenerator>(source + DispatcherQueueDefinition);

Assert.AreEqual(1, result.GeneratedTrees.Length, "More trees generated than expected.");
// To do, should probably inspect tree more directly.
var generatedSource = result.GeneratedTrees.First().ToString();
Assert.IsFalse(generatedSource.Contains("await LoadTestContentAsync"), "Saw a loading call.");
Assert.IsFalse(generatedSource.Contains("await UnloadTestContentAsync"), "Saw an unloading call.");
Assert.IsTrue(generatedSource.Contains("TestMethod();"), "Didn't see expected running of test.");
Assert.IsFalse(generatedSource.Contains("await TestMethod();"), "Sync method ran async instead.");
}

/// <summary>
Expand All @@ -242,10 +289,10 @@ public void TestMethod()
/// <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)
private static GeneratorDriverRunResult VerifyGeneratedDiagnostics<TGenerator>(string source, params string[] diagnosticsIds)
where TGenerator : class, IIncrementalGenerator, new()
{
VerifyGeneratedDiagnostics<TGenerator>(CSharpSyntaxTree.ParseText(source), diagnosticsIds);
return VerifyGeneratedDiagnostics<TGenerator>(CSharpSyntaxTree.ParseText(source), diagnosticsIds);
}

/// <summary>
Expand All @@ -255,7 +302,7 @@ private static void VerifyGeneratedDiagnostics<TGenerator>(string source, params
/// <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)
private static GeneratorDriverRunResult VerifyGeneratedDiagnostics<TGenerator>(SyntaxTree syntaxTree, params string[] diagnosticsIds)
where TGenerator : class, IIncrementalGenerator, new()
{
var attributeType = typeof(LabsUITestMethodAttribute);
Expand Down Expand Up @@ -283,7 +330,7 @@ private static void VerifyGeneratedDiagnostics<TGenerator>(SyntaxTree syntaxTree
.Create(generator)
.WithUpdatedParseOptions((CSharpParseOptions)syntaxTree.Options);

_ = driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation outputCompilation, out ImmutableArray<Diagnostic> diagnostics);
driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation outputCompilation, out ImmutableArray<Diagnostic> diagnostics);

HashSet<string> resultingIds = diagnostics.Select(diagnostic => diagnostic.Id).ToHashSet();
var generatedCompilationDiaghostics = outputCompilation.GetDiagnostics();
Expand All @@ -292,5 +339,14 @@ private static void VerifyGeneratedDiagnostics<TGenerator>(SyntaxTree syntaxTree
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);

var result = driver.GetRunResult();

if (diagnosticsIds.Length == 0)
{
Assert.IsTrue(result.GeneratedTrees.Length > 0, "Generator did not produce any output!");
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

.Where(static item => item.Attribute is not null && item.Symbol is IMethodSymbol)
.Select(static (x, _) => (IMethodSymbol)x.Symbol)

.Select(static (x, _) => (MethodSymbol: x, ControlTypeSymbol: GetControlTypeSymbolFromMethodParameters(x)))

.Where(static x => x.ControlTypeSymbol is not null)
.Select(static (x, _) => (x.MethodSymbol, ControlTypeSymbol: x.ControlTypeSymbol!));
.Select(static (x, _) => (MethodSymbol: x, ControlTypeSymbol: GetControlTypeSymbolFromMethodParameters(x)));
Arlodotexe marked this conversation as resolved.
Show resolved Hide resolved

// Generate source
context.RegisterSourceOutput(methodAndPageTypeSymbols, (x, y) => GenerateTestMethod(x, y.MethodSymbol, y.ControlTypeSymbol));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,131 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using CommunityToolkit.Labs.Core.SourceGenerators.LabsUITestMethod;
using CommunityToolkit.Labs.UnitTests;

namespace ProjectTemplate.Tests;

[TestClass]
public class ExampleProjectTemplateTestClass
public partial class ExampleProjectTemplateTestClass : VisualUITestBase
{
// TODO: https://github.com/CommunityToolkit/Labs-Windows/issues/160
// If you don't need access to UI objects directly or async code, use this pattern.
[TestMethod]
public void SimpleSynchronousExampleTest()
{
var assembly = typeof(ProjectTemplate_ClassicBinding).Assembly;
var type = assembly.GetType(typeof(ProjectTemplate_ClassicBinding).FullName ?? string.Empty);

Assert.IsNotNull(type, "Could not find ProjectTemplate_ClassicBinding type.");
Assert.AreEqual(typeof(ProjectTemplate_ClassicBinding), type, "Type of ProjectTemplate_ClassicBinding does not match expected type.");
}

// If you don't need access to UI objects directly, use this pattern.
[TestMethod]
public async Task SimpleExampleTest()
public async Task SimpleAsyncExampleTest()
{
await Task.Delay(250);

Assert.IsTrue(true);
}

// Example that shows how to check for exception throwing.
[TestMethod]
public void SimpleExceptionCheckTest()
{
// If you need to check exceptions occur for invalid inputs, etc...
// Use Assert.ThrowsException to limit the scope to where you expect the error to occur.
// Otherwise, using the ExpectedException attribute could swallow or
// catch other issues in setup code.
Assert.ThrowsException<NotImplementedException>(() => throw new NotImplementedException());
}

// The LabsUITestMethod automatically dispatches to the UI for us to work with UI objects.
[LabsUITestMethod]
public void SimpleUIAttributeExampleTest()
{
var component = new ProjectTemplate_ClassicBinding();
Assert.IsNotNull(component);
}

// The LabsUITestMethod can also easily grab a XAML Page for us by passing its type as a parameter.
// This lets us actually test a control as it would behave within an actual application.
// The page will already be loaded by the time your test is called.
[LabsUITestMethod]
public void SimpleUIExamplePageTest(ExampleProjectTemplateTestPage page)
{
// You can use the Toolkit Visual Tree helpers here to find the component by type or name:
var component = page.FindDescendant<ProjectTemplate_ClassicBinding>();

Assert.IsNotNull(component);

var componentByName = page.FindDescendant("ProjectTemplateControl");

Assert.IsNotNull(componentByName);
}

// You can still do async work with a LabsUITestMethod as well.
[LabsUITestMethod]
public async Task SimpleAsyncUIExamplePageTest(ExampleProjectTemplateTestPage page)
{
await CommunityToolkit.Labs.UnitTests.App.DispatcherQueue.EnqueueAsync(() =>
// This helper can be used to wait for a rendering pass to complete.
await CompositionTargetHelper.ExecuteAfterCompositionRenderingAsync(() => { });

var component = page.FindDescendant<ProjectTemplate_ClassicBinding>();

Assert.IsNotNull(component);
}

//// ----------------------------- ADVANCED TEST SCENARIOS -----------------------------

// If you need to use DataRow, you can use this pattern with the UI dispatch still.
// Otherwise, checkout the LabsUITestMethod attribute above.
// See https://github.com/CommunityToolkit/Labs-Windows/issues/186
[TestMethod]
public async Task ComplexAsyncUIExampleTest()
Arlodotexe marked this conversation as resolved.
Show resolved Hide resolved
{
await App.DispatcherQueue.EnqueueAsync(() =>
Arlodotexe marked this conversation as resolved.
Show resolved Hide resolved
{
var systemUnderTest = new ProjectTemplate_ClassicBinding();
Assert.IsNotNull(systemUnderTest);
var component = new ProjectTemplate_ClassicBinding();
Assert.IsNotNull(component);
});
}

// If you want to load other content not within a XAML page using the LabsUITestMethod above.
// Then you can do that using the Load/UnloadTestContentAsync methods.
[TestMethod]
public async Task ComplexAsyncLoadUIExampleTest()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
{
var component = new ProjectTemplate_ClassicBinding();
Assert.IsNotNull(component);
Assert.IsFalse(component.IsLoaded);

await LoadTestContentAsync(component);

Assert.IsTrue(component.IsLoaded);

await UnloadTestContentAsync(component);

Assert.IsFalse(component.IsLoaded);
});
}

// You can still use the LabsUITestMethod to remove the extra layer for the dispatcher as well:
[LabsUITestMethod]
public async Task ComplexAsyncLoadUIExampleWithoutDispatcherTest()
{
var component = new ProjectTemplate_ClassicBinding();
Assert.IsNotNull(component);
Assert.IsFalse(component.IsLoaded);

await LoadTestContentAsync(component);

Assert.IsTrue(component.IsLoaded);

await UnloadTestContentAsync(component);

Assert.IsFalse(component.IsLoaded);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- 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. -->
<Page x:Class="ProjectTemplate.Tests.ExampleProjectTemplateTestPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
xmlns:local="using:ProjectTemplate.Tests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">

<Grid>
<labs:ProjectTemplate_ClassicBinding x:Name="ProjectTemplateControl" />
</Grid>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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.

namespace ProjectTemplate.Tests;

/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ExampleProjectTemplateTestPage : Page
{
public ExampleProjectTemplateTestPage()
{
this.InitializeComponent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,14 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)ExampleProjectTemplateTestClass.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ExampleProjectTemplateTestPage.xaml.cs">
<DependentUpon>ExampleProjectTemplateTestPage.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="$(MSBuildThisFileDirectory)ExampleProjectTemplateTestPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>