Harden retail character selection recovery
This commit is contained in:
parent
6cfab727f1
commit
aeac874dab
8 changed files with 736 additions and 81 deletions
|
|
@ -440,6 +440,108 @@ public sealed class RetailDialogFactoryTests
|
|||
Assert.Null(root.KeyboardFocus);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(RetailDialogType.Wait, 0)]
|
||||
[InlineData(RetailDialogType.Message, 1)]
|
||||
[InlineData(RetailDialogType.ConfirmationTextInput, 2)]
|
||||
public void CatalogFailure_DoesNotPoisonActiveQueue_AndTickRecovers(
|
||||
RetailDialogType type,
|
||||
int failureKind)
|
||||
{
|
||||
var root = new UiRoot { Width = 800f, Height = 600f };
|
||||
bool available = false;
|
||||
int attempts = 0;
|
||||
using var factory = new RetailDialogFactory(root, requested =>
|
||||
{
|
||||
Assert.Equal(type, requested);
|
||||
attempts++;
|
||||
if (!available)
|
||||
{
|
||||
return failureKind switch
|
||||
{
|
||||
0 => throw new InvalidOperationException("catalog unavailable"),
|
||||
1 => null,
|
||||
_ => new ImportedLayout(
|
||||
new UiDialogRoot(),
|
||||
new Dictionary<uint, UiElement>()),
|
||||
};
|
||||
}
|
||||
return BuildDialogLayout(type);
|
||||
});
|
||||
RetailDialogData data = type switch
|
||||
{
|
||||
RetailDialogType.Wait => RetailDialogData.Wait("Please Wait"),
|
||||
RetailDialogType.Message => RetailDialogData.Message("Error"),
|
||||
_ => RetailDialogData.ConfirmationTextInput("Type DELETE"),
|
||||
};
|
||||
|
||||
uint context = 0u;
|
||||
Exception? creationError = Record.Exception(
|
||||
() => context = factory.MakeDialog(data));
|
||||
|
||||
Assert.Null(creationError);
|
||||
Assert.NotEqual(0u, context);
|
||||
Assert.Equal(0, factory.ActiveCount);
|
||||
Assert.Equal(0, factory.PendingCount);
|
||||
Assert.Equal(1, factory.RetryCount);
|
||||
Assert.Null(root.Modal);
|
||||
Assert.Empty(root.Children);
|
||||
|
||||
available = true;
|
||||
factory.Tick();
|
||||
|
||||
Assert.Equal(2, attempts);
|
||||
Assert.Equal(1, factory.ActiveCount);
|
||||
Assert.Equal(0, factory.PendingCount);
|
||||
Assert.Equal(0, factory.RetryCount);
|
||||
Assert.NotNull(root.Modal);
|
||||
Assert.True(factory.CloseDialog(context));
|
||||
Assert.False(factory.IsOpen);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PendingCatalogFailure_MovesOutOfQueue_ThenRecoversBeforeLaterWork()
|
||||
{
|
||||
var root = new UiRoot { Width = 800f, Height = 600f };
|
||||
bool messageAvailable = false;
|
||||
var layouts = new List<(RetailDialogType Type, ImportedLayout Layout)>();
|
||||
using var factory = new RetailDialogFactory(root, type =>
|
||||
{
|
||||
if (type == RetailDialogType.Message && !messageAvailable)
|
||||
return null;
|
||||
ImportedLayout layout = BuildDialogLayout(type);
|
||||
layouts.Add((type, layout));
|
||||
return layout;
|
||||
});
|
||||
|
||||
uint active = factory.MakeWait("active");
|
||||
uint failed = factory.MakeMessage("recover me");
|
||||
uint later = factory.MakeWait("later");
|
||||
Assert.Equal(2, factory.PendingCount);
|
||||
|
||||
Assert.True(factory.CloseDialog(active));
|
||||
|
||||
Assert.Equal(0, factory.ActiveCount);
|
||||
Assert.Equal(1, factory.PendingCount);
|
||||
Assert.Equal(1, factory.RetryCount);
|
||||
Assert.Null(root.Modal);
|
||||
|
||||
messageAvailable = true;
|
||||
factory.Tick();
|
||||
|
||||
Assert.Equal(1, factory.ActiveCount);
|
||||
Assert.Equal(1, factory.PendingCount);
|
||||
Assert.Equal(0, factory.RetryCount);
|
||||
Assert.Equal(
|
||||
"recover me",
|
||||
MessageFromAnyDialog(layouts.Last(static entry =>
|
||||
entry.Type == RetailDialogType.Message).Layout.Root));
|
||||
|
||||
Assert.True(factory.CloseDialog(failed));
|
||||
Assert.Equal("later", MessageFromAnyDialog(root.Modal!));
|
||||
Assert.True(factory.CloseDialog(later));
|
||||
}
|
||||
|
||||
private static RetailDialogFactory CreateFactory(
|
||||
UiRoot root,
|
||||
List<ImportedLayout> layouts)
|
||||
|
|
@ -464,6 +566,15 @@ public sealed class RetailDialogFactoryTests
|
|||
=> string.Join(" ", Assert.IsType<UiText>(layout.FindElement(
|
||||
RetailConfirmationDialogView.MessageElementId)).LinesProvider().Select(static line => line.Text));
|
||||
|
||||
private static string MessageFromAnyDialog(UiElement root)
|
||||
=> string.Join(
|
||||
" ",
|
||||
Assert.IsType<UiText>(UiElement.FindDescendant(
|
||||
root,
|
||||
RetailConfirmationDialogView.MessageElementId))
|
||||
.LinesProvider()
|
||||
.Select(static line => line.Text));
|
||||
|
||||
internal static ImportedLayout BuildDialogLayout(RetailDialogType type)
|
||||
{
|
||||
uint rootId = RetailDialogFactory.RootElementId(type);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue