Improve shared MAUI controls and tests

This commit is contained in:
Andy Howard
2026-10-06 14:13:28 +01:00
parent 0406adfc99
commit 5daf7ce97f
106 changed files with 2299 additions and 805 deletions
+144
View File
@@ -0,0 +1,144 @@
namespace SacsMobileMauiTestHost;
public partial class MainPage : ContentPage
{
private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(15);
public MainPage()
{
InitializeComponent();
}
// --- Test Runner ---
private async void OnRunTestsClicked(object? sender, EventArgs e)
{
await RunTestsAsync(RunDispatcherTestsAsync);
}
private async void OnRunDialogTestsClicked(object? sender, EventArgs e)
{
await RunTestsAsync(RunDialogTestsAsync);
}
private async void OnRunDatePickerTestsClicked(object? sender, EventArgs e)
{
await RunTestsAsync(RunDatePickerTestsAsync);
}
private async Task RunTestsAsync(Func<Task<(List<String> results, int passed, int failed)>> runTests)
{
RunTestsButton.IsEnabled = false;
RunDialogTestsButton.IsEnabled = false;
RunDatePickerTestsButton.IsEnabled = false;
StatusLabel.Text = "Running...";
ResultsLabel.Text = String.Empty;
try
{
(List<String> results, int passed, int failed) = await Task.Run(runTests);
ResultsLabel.Text = String.Join(Environment.NewLine, results);
StatusLabel.Text = failed == 0 ? $"Passed: {passed}" : $"Passed: {passed}; failed: {failed}";
}
catch (Exception exception)
{
StatusLabel.Text = "Test runner failed.";
ResultsLabel.Text = exception.ToString();
}
finally
{
RunTestsButton.IsEnabled = true;
RunDialogTestsButton.IsEnabled = true;
RunDatePickerTestsButton.IsEnabled = true;
}
}
private static async Task<(List<String> results, int passed, int failed)> RunDispatcherTestsAsync()
{
Sarand.UnitTests.Mobile.Maui.Utils.SamThreadUtil_Tester tests = new();
List<String> results = new();
int passed = 0;
int failed = 0;
await RunTestAsync(nameof(tests.PostToMainThread_ExecutesAction), () => tests.PostToMainThread_ExecutesAction());
await RunTestAsync(nameof(tests.InvokeOnMainThreadAsync_Action_CompletesOnMainThread), () => tests.InvokeOnMainThreadAsync_Action_CompletesOnMainThread());
await RunTestAsync(nameof(tests.InvokeOnMainThreadAsync_AsyncAction_CompletesOnMainThread), () => tests.InvokeOnMainThreadAsync_AsyncAction_CompletesOnMainThread());
await RunTestAsync(nameof(tests.InvokeOnMainThreadAsync_ReturnsSynchronousResult), () => tests.InvokeOnMainThreadAsync_ReturnsSynchronousResult());
await RunTestAsync(nameof(tests.InvokeOnMainThreadAsync_ReturnsAsynchronousResult), () => tests.InvokeOnMainThreadAsync_ReturnsAsynchronousResult());
await RunTestAsync(nameof(tests.InvokeOnMainThreadAsync_PropagatesException), () =>
{
tests.InvokeOnMainThreadAsync_PropagatesException();
return Task.CompletedTask;
});
return (results, passed, failed);
async Task RunTestAsync(String name, Func<Task> test)
{
try
{
await test().WaitAsync(TestTimeout);
results.Add($"PASS {name}");
passed++;
}
catch (Exception exception)
{
results.Add($"FAIL {name}: {exception.GetBaseException().Message}");
failed++;
}
}
}
private static async Task<(List<String> results, int passed, int failed)> RunDialogTestsAsync()
{
Sarand.UnitTests.Mobile.Maui.Utils.SamThreadUtil_Tester tests = new();
List<String> results = new();
int passed = 0;
int failed = 0;
await RunTestAsync(nameof(tests.DisplayAlertAsync_CompletesAfterUserDismissesAlert), () => tests.DisplayAlertAsync_CompletesAfterUserDismissesAlert());
await RunTestAsync(nameof(tests.DisplayConfirmAsync_ReturnsTrueWhenAcceptIsSelected), () => tests.DisplayConfirmAsync_ReturnsTrueWhenAcceptIsSelected());
await RunTestAsync(nameof(tests.DisplayConfirmAsync_ReturnsFalseWhenCancelIsSelected), () => tests.DisplayConfirmAsync_ReturnsFalseWhenCancelIsSelected());
return (results, passed, failed);
async Task RunTestAsync(String name, Func<Task> test)
{
try
{
await test().WaitAsync(TimeSpan.FromMinutes(2));
results.Add($"PASS {name}");
passed++;
}
catch (Exception exception)
{
results.Add($"FAIL {name}: {exception.GetBaseException().Message}");
failed++;
}
}
}
private static async Task<(List<String> results, int passed, int failed)> RunDatePickerTestsAsync()
{
Sarand.UnitTests.Mobile.Maui.Controls.SamDatePicker_Tester tests = new();
List<String> results = new();
int passed = 0;
int failed = 0;
try
{
await tests.AllowInvalid_TransitionsRefreshDisplayAndDateReset().WaitAsync(TestTimeout);
results.Add("PASS AllowInvalid_TransitionsRefreshDisplayAndDateReset");
passed++;
}
catch (Exception exception)
{
results.Add($"FAIL AllowInvalid_TransitionsRefreshDisplayAndDateReset: {exception.GetBaseException().Message}");
failed++;
}
return (results, passed, failed);
}
// --- The End ---
}