更新框架
This commit is contained in:
1 parent
ef50fa0620
commit
84b28f9672
72 files changed
+2222
-282
No files matched your search
@@ -0,0 +1,86 @@
|
||||
using MAX.Notification.NotificationPublishers;
|
||||
using MAX.Notification;
|
||||
|
||||
var calls = new List<int>();
|
||||
var services = new TestServices();
|
||||
services.Handlers = [new First((_, _) => { calls.Add(1); return Task.CompletedTask; }),
|
||||
new First((_, _) => { calls.Add(99); return Task.CompletedTask; }),
|
||||
new Second((_, _) => { calls.Add(2); return Task.CompletedTask; })];
|
||||
var publisher = new NotificationPublisher(services);
|
||||
INotification message = new Changed();
|
||||
await publisher.Publish(message);
|
||||
Check(calls.SequenceEqual([1, 2]), "运行时类型分发、顺序和类型去重");
|
||||
calls.Clear();
|
||||
await publisher.Publish((object)message);
|
||||
Check(calls.SequenceEqual([1, 2]) && services.Resolutions == 2, "对象分发和每次重新解析");
|
||||
services.Handlers = [];
|
||||
await publisher.Publish(message);
|
||||
services.Handlers = null;
|
||||
await publisher.Publish(message);
|
||||
await Throws<ArgumentNullException>(() => publisher.Publish((object)null!));
|
||||
await Throws<ArgumentException>(() => publisher.Publish(new object()));
|
||||
await Throws<ArgumentNullException>(() => Task.FromResult(new NotificationPublisher(services, null!)));
|
||||
using var cancelled = new CancellationTokenSource();
|
||||
cancelled.Cancel();
|
||||
// 原版只传递取消令牌;没有处理器时即使已取消也正常完成。
|
||||
await publisher.Publish(message, cancelled.Token);
|
||||
|
||||
services.Handlers = [new First((_, _) => throw new InvalidOperationException("expected")),
|
||||
new Second((_, _) => { calls.Add(3); return Task.CompletedTask; })];
|
||||
calls.Clear();
|
||||
await Throws<InvalidOperationException>(() => publisher.Publish(message));
|
||||
Check(calls.Count == 0, "顺序模式失败后停止");
|
||||
await Throws<InvalidOperationException>(() => new NotificationPublisher(services,
|
||||
new TaskWhenAllPublisher()).Publish(message));
|
||||
Check(calls.Count == 0, "原版并发模式同步异常阻止后续枚举");
|
||||
|
||||
var gate = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var started = 0;
|
||||
Task Handle(Changed _, CancellationToken token)
|
||||
{
|
||||
Check(token == cancelled.Token || !token.IsCancellationRequested, "取消令牌传递");
|
||||
if (++started == 2) gate.SetResult();
|
||||
return gate.Task;
|
||||
}
|
||||
services.Handlers = [new First(Handle), new Second(Handle)];
|
||||
await new NotificationPublisher(services, new TaskWhenAllPublisher())
|
||||
.Publish(message).WaitAsync(TimeSpan.FromSeconds(5));
|
||||
Check(started == 2, "并发启动和等待全部完成");
|
||||
|
||||
using var during = new CancellationTokenSource();
|
||||
services.Handlers = [new First((_, token) => { Check(token == during.Token, "原始令牌"); during.Cancel(); return Task.CompletedTask; }),
|
||||
new Second((_, token) => { token.ThrowIfCancellationRequested(); return Task.CompletedTask; })];
|
||||
await Throws<OperationCanceledException>(() => publisher.Publish(message, during.Token));
|
||||
Console.WriteLine("All notification smoke tests passed.");
|
||||
|
||||
static void Check(bool condition, string name)
|
||||
{
|
||||
if (!condition) throw new Exception($"检查失败:{name}");
|
||||
}
|
||||
static async Task Throws<T>(Func<Task> action) where T : Exception
|
||||
{
|
||||
try { await action(); }
|
||||
catch (T) { return; }
|
||||
throw new Exception($"预期异常:{typeof(T).Name}");
|
||||
}
|
||||
sealed record Changed : INotification;
|
||||
sealed class First(Func<Changed, CancellationToken, Task> action) : INotificationHandler<Changed>
|
||||
{
|
||||
public Task Handle(Changed notification, CancellationToken cancellationToken) => action(notification, cancellationToken);
|
||||
}
|
||||
sealed class Second(Func<Changed, CancellationToken, Task> action) : INotificationHandler<Changed>
|
||||
{
|
||||
public Task Handle(Changed notification, CancellationToken cancellationToken) => action(notification, cancellationToken);
|
||||
}
|
||||
sealed class TestServices : IServiceProvider
|
||||
{
|
||||
public INotificationHandler<Changed>[]? Handlers { get; set; }
|
||||
public int Resolutions { get; private set; }
|
||||
public object? GetService(Type serviceType)
|
||||
{
|
||||
if (serviceType != typeof(IEnumerable<INotificationHandler<Changed>>))
|
||||
throw new Exception($"错误的解析类型:{serviceType}");
|
||||
Resolutions++;
|
||||
return Handlers;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user