test(app): freeze GameWindow lifecycle boundaries
Pin the accepted startup, input, frame, resize, shutdown, and native-window order before Slice 8 moves those edges, while deleting only unread duplicate state and test-only GameWindow facades. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
20ebf217e2
commit
476c2e6de1
7 changed files with 380 additions and 56 deletions
|
|
@ -78,4 +78,85 @@ public sealed class ResourceShutdownTransactionTests
|
|||
Assert.Equal(1, calls);
|
||||
Assert.True(transaction.IsComplete);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PersistentFailuresInOneStageAreAllAttemptedAndNamed()
|
||||
{
|
||||
int firstCalls = 0;
|
||||
int secondCalls = 0;
|
||||
var transaction = new ResourceShutdownTransaction(
|
||||
new ResourceShutdownStage("owners",
|
||||
[
|
||||
new("first", () =>
|
||||
{
|
||||
firstCalls++;
|
||||
throw new InvalidOperationException("first failure");
|
||||
}),
|
||||
new("second", () =>
|
||||
{
|
||||
secondCalls++;
|
||||
throw new InvalidOperationException("second failure");
|
||||
}),
|
||||
]));
|
||||
|
||||
AggregateException error = Assert.Throws<AggregateException>(
|
||||
transaction.CompleteOrThrow);
|
||||
|
||||
Assert.True(firstCalls > 0);
|
||||
Assert.Equal(firstCalls, secondCalls);
|
||||
Assert.Contains(
|
||||
error.InnerExceptions,
|
||||
exception => exception.Message.Contains("first", StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
error.InnerExceptions,
|
||||
exception => exception.Message.Contains("second", StringComparison.Ordinal));
|
||||
Assert.False(transaction.IsComplete);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExplicitRetryAfterFailedCompletionDoesNotReplaySuccessfulOperations()
|
||||
{
|
||||
int completeCalls = 0;
|
||||
int pendingCalls = 0;
|
||||
bool allowPending = false;
|
||||
var transaction = new ResourceShutdownTransaction(
|
||||
new ResourceShutdownStage("owners",
|
||||
[
|
||||
new("complete", () => completeCalls++),
|
||||
new("pending", () =>
|
||||
{
|
||||
pendingCalls++;
|
||||
if (!allowPending)
|
||||
throw new InvalidOperationException("not yet");
|
||||
}),
|
||||
]));
|
||||
|
||||
Assert.Throws<AggregateException>(transaction.CompleteOrThrow);
|
||||
int pendingCallsBeforeRetry = pendingCalls;
|
||||
allowPending = true;
|
||||
|
||||
transaction.CompleteOrThrow();
|
||||
|
||||
Assert.Equal(1, completeCalls);
|
||||
Assert.Equal(pendingCallsBeforeRetry + 1, pendingCalls);
|
||||
Assert.True(transaction.IsComplete);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyStagesConvergeWithoutSkippingLaterOperations()
|
||||
{
|
||||
int calls = 0;
|
||||
var transaction = new ResourceShutdownTransaction(
|
||||
new ResourceShutdownStage("empty", []),
|
||||
new ResourceShutdownStage("owner",
|
||||
[
|
||||
new("owner", () => calls++),
|
||||
]),
|
||||
new ResourceShutdownStage("empty tail", []));
|
||||
|
||||
transaction.CompleteOrThrow();
|
||||
|
||||
Assert.Equal(1, calls);
|
||||
Assert.True(transaction.IsComplete);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue