Skip to content

Commit c20e665

Browse files
committed
#9 Fixed unit tests
1 parent 9c34dda commit c20e665

File tree

2 files changed

+58
-40
lines changed

2 files changed

+58
-40
lines changed

BFF.DataVirtualizingCollection/PageStorage/AsyncPageBase.cs

+36-19
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ internal abstract class AsyncPageBase<T> : IPage<T>
1515
protected readonly int Offset;
1616
protected readonly int PageSize;
1717
private readonly IDisposable _onDisposalAfterFetchCompleted;
18+
private readonly IAsyncPageFetchScheduler _asyncPageFetchScheduler;
1819
protected readonly IObserver<(int Offset, int PageSize, T[] PreviousPage, T[] Page)> PageArrivalObservations;
19-
private readonly CancellationTokenSource _cancellationTokenSource = new();
20+
protected readonly CancellationTokenSource CancellationTokenSource = new();
2021
protected T[] Page;
2122
protected bool IsDisposed;
2223

@@ -30,32 +31,29 @@ internal AsyncPageBase(
3031
// dependencies
3132
Func<int, int, T> placeholderFactory,
3233
IAsyncPageFetchScheduler asyncPageFetchScheduler,
33-
IScheduler pageBackgroundScheduler,
3434
IObserver<(int Offset, int PageSize, T[] PreviousPage, T[] Page)> pageArrivalObservations)
3535
{
3636
Offset = offset;
3737
PageSize = pageSize;
3838
_onDisposalAfterFetchCompleted = onDisposalAfterFetchCompleted;
39+
_asyncPageFetchScheduler = asyncPageFetchScheduler;
3940
PageArrivalObservations = pageArrivalObservations;
4041
Page = Enumerable
4142
.Range(0, pageSize)
4243
.Select(pageIndex => placeholderFactory(pageKey, pageIndex))
4344
.ToArray();
44-
PageFetchCompletion = Observable
45-
.StartAsync(FetchPage, pageBackgroundScheduler)
46-
.ToTask(_cancellationTokenSource.Token);
45+
}
4746

48-
async Task FetchPage(CancellationToken ct)
49-
{
50-
await asyncPageFetchScheduler.Schedule().ConfigureAwait(false);
51-
ct.ThrowIfCancellationRequested();
52-
await FetchPageInner(ct).ConfigureAwait(false);
53-
}
47+
protected async Task FetchPage(CancellationToken ct)
48+
{
49+
await _asyncPageFetchScheduler.Schedule().ConfigureAwait(false);
50+
ct.ThrowIfCancellationRequested();
51+
await FetchPageInner(ct).ConfigureAwait(false);
5452
}
5553

5654
protected abstract Task FetchPageInner(CancellationToken ct);
5755

58-
public Task PageFetchCompletion { get; }
56+
public abstract Task PageFetchCompletion { get; }
5957

6058
public T this[int index] =>
6159
index >= PageSize || index < 0
@@ -76,7 +74,7 @@ public async ValueTask DisposeAsync()
7674
IsDisposed = true;
7775
try
7876
{
79-
_cancellationTokenSource.Cancel();
77+
CancellationTokenSource.Cancel();
8078
await PageFetchCompletion.ConfigureAwait(false);
8179
}
8280
catch (OperationCanceledException)
@@ -116,12 +114,17 @@ internal AsyncNonTaskBasedPage(
116114
onDisposalAfterFetchCompleted,
117115
placeholderFactory,
118116
asyncPageFetchScheduler,
119-
pageBackgroundScheduler,
120-
pageArrivalObservations) =>
117+
pageArrivalObservations)
118+
{
121119
_pageFetcher = pageFetcher;
120+
PageFetchCompletion = Observable
121+
.StartAsync(FetchPage, pageBackgroundScheduler)
122+
.ToTask(CancellationTokenSource.Token);
123+
}
122124

123125
protected override async Task FetchPageInner(CancellationToken ct)
124126
{
127+
await Task.Delay(1, ct).ConfigureAwait(false);
125128
var previousPage = Page;
126129
Page = _pageFetcher(Offset, PageSize, ct);
127130
await DisposePageItems(previousPage).ConfigureAwait(false);
@@ -130,6 +133,8 @@ protected override async Task FetchPageInner(CancellationToken ct)
130133
else
131134
await DisposePageItems(Page).ConfigureAwait(false);
132135
}
136+
137+
public override Task PageFetchCompletion { get; }
133138
}
134139

135140
internal sealed class AsyncTaskBasedPage<T> : AsyncPageBase<T>
@@ -156,9 +161,13 @@ internal AsyncTaskBasedPage(
156161
onDisposalAfterFetchCompleted,
157162
placeholderFactory,
158163
asyncPageFetchScheduler,
159-
pageBackgroundScheduler,
160-
pageArrivalObservations) =>
164+
pageArrivalObservations)
165+
{
161166
_pageFetcher = pageFetcher;
167+
PageFetchCompletion = Observable
168+
.StartAsync(FetchPage, pageBackgroundScheduler)
169+
.ToTask(CancellationTokenSource.Token);
170+
}
162171

163172
protected override async Task FetchPageInner(CancellationToken ct)
164173
{
@@ -170,6 +179,8 @@ protected override async Task FetchPageInner(CancellationToken ct)
170179
else
171180
await DisposePageItems(Page).ConfigureAwait(false);
172181
}
182+
183+
public override Task PageFetchCompletion { get; }
173184
}
174185

175186
internal sealed class AsyncEnumerableBasedPage<T> : AsyncPageBase<T>
@@ -196,9 +207,13 @@ internal AsyncEnumerableBasedPage(
196207
onDisposalAfterFetchCompleted,
197208
placeholderFactory,
198209
asyncPageFetchScheduler,
199-
pageBackgroundScheduler,
200-
pageArrivalObservations) =>
210+
pageArrivalObservations)
211+
{
201212
_pageFetcher = pageFetcher;
213+
PageFetchCompletion = Observable
214+
.StartAsync(FetchPage, pageBackgroundScheduler)
215+
.ToTask(CancellationTokenSource.Token);
216+
}
202217

203218
protected override async Task FetchPageInner(CancellationToken ct)
204219
{
@@ -216,5 +231,7 @@ protected override async Task FetchPageInner(CancellationToken ct)
216231
i++;
217232
}
218233
}
234+
235+
public override Task PageFetchCompletion { get; }
219236
}
220237
}

Tests.Unit/PageStorage/AsyncPageBaseTests.cs

+22-21
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ internal async Task Dispose_PageHasOneDisposable_Disposes()
2626
var isDisposed = new TaskCompletionSource<Unit>();
2727
var disposable = Disposable.Create(() => isDisposed.SetResult(Unit.Default));
2828
var sut = PageWithDisposable(disposable);
29+
await sut.PageFetchCompletion.ConfigureAwait(false);
2930

3031
// Act
3132
await sut.DisposeAsync().ConfigureAwait(false);
@@ -86,12 +87,12 @@ public class AsyncNonTaskBasedPageTests : AsyncPageBaseTestsBase
8687
0,
8788
1,
8889
Disposable.Empty,
89-
(offset, pageSize, _) =>
90+
(_, _, _) =>
9091
{
9192
Thread.Sleep(10);
9293
return new[] { 69 };
9394
},
94-
(_, __) => 23,
95+
(_, _) => 23,
9596
new ImmediateAsyncPageFetchScheduler(),
9697
DefaultScheduler.Instance,
9798
Observer.Create<(int Offset, int PageSize, int[] PreviousPage, int[] Page)>(_ => { }));
@@ -102,12 +103,12 @@ public class AsyncNonTaskBasedPageTests : AsyncPageBaseTestsBase
102103
0,
103104
1,
104105
Disposable.Empty,
105-
(offset, pageSize, _) =>
106+
(_, _, _) =>
106107
{
107-
Thread.Sleep(10);
108+
Thread.Sleep(1000);
108109
return new[] {69};
109110
},
110-
(_, __) => 23,
111+
(_, _) => 23,
111112
new ImmediateAsyncPageFetchScheduler(),
112113
DefaultScheduler.Instance,
113114
Observer.Create<(int Offset, int PageSize, int[] PreviousPage, int[] Page)>(_ => { }));
@@ -120,12 +121,12 @@ internal override AsyncPageBase<IDisposable> PageWithDisposable(IDisposable disp
120121
0,
121122
1,
122123
Disposable.Empty,
123-
(offset, pageSize, _) =>
124+
(_, _, _) =>
124125
{
125126
Thread.Sleep(10);
126127
return new[] { disposable };
127128
},
128-
(_, __) => Disposable.Empty,
129+
(_, _) => Disposable.Empty,
129130
new ImmediateAsyncPageFetchScheduler(),
130131
DefaultScheduler.Instance,
131132
Observer.Create<(int Offset, int PageSize, IDisposable[] PreviousPage, IDisposable[] Page)>(_ => { }));
@@ -139,12 +140,12 @@ internal override AsyncPageBase<IDisposable> PageWithDisposablePlaceholder(IDisp
139140
0,
140141
1,
141142
Disposable.Empty,
142-
(offset, pageSize, _) =>
143+
(_, _, _) =>
143144
{
144145
Thread.Sleep(10);
145146
return new []{ Disposable.Empty };
146147
},
147-
(_, __) => disposable,
148+
(_, _) => disposable,
148149
new ImmediateAsyncPageFetchScheduler(),
149150
DefaultScheduler.Instance,
150151
Observer.Create<(int Offset, int PageSize, IDisposable[] PreviousPage, IDisposable[] Page)>(_ => { }));
@@ -160,12 +161,12 @@ public class AsyncTaskBasedPageTests : AsyncPageBaseTestsBase
160161
0,
161162
1,
162163
Disposable.Empty,
163-
async (offset, pageSize, _) =>
164+
async (_, _, ct) =>
164165
{
165-
await Task.Delay(10);
166+
await Task.Delay(10, ct).ConfigureAwait(false);
166167
return new[] { 69 };
167168
},
168-
(_, __) => 23,
169+
(_, _) => 23,
169170
new ImmediateAsyncPageFetchScheduler(),
170171
DefaultScheduler.Instance,
171172
Observer.Create<(int Offset, int PageSize, int[] PreviousPage, int[] Page)>(_ => { }));
@@ -176,12 +177,12 @@ public class AsyncTaskBasedPageTests : AsyncPageBaseTestsBase
176177
0,
177178
1,
178179
Disposable.Empty,
179-
async (offset, pageSize, _) =>
180+
async (_, _, ct) =>
180181
{
181-
await Task.Delay(10);
182+
await Task.Delay(10, ct).ConfigureAwait(false);
182183
return new[] {69};
183184
},
184-
(_, __) => 23,
185+
(_, _) => 23,
185186
new ImmediateAsyncPageFetchScheduler(),
186187
DefaultScheduler.Instance,
187188
Observer.Create<(int Offset, int PageSize, int[] PreviousPage, int[] Page)>(_ => { }));
@@ -194,12 +195,12 @@ internal override AsyncPageBase<IDisposable> PageWithDisposable(IDisposable disp
194195
0,
195196
1,
196197
Disposable.Empty,
197-
async (offset, pageSize, _) =>
198+
async (_, _, ct) =>
198199
{
199-
await Task.Delay(10).ConfigureAwait(false);
200+
await Task.Delay(10, ct).ConfigureAwait(false);
200201
return new[] { disposable };
201202
},
202-
(_, __) => Disposable.Empty,
203+
(_, _) => Disposable.Empty,
203204
new ImmediateAsyncPageFetchScheduler(),
204205
DefaultScheduler.Instance,
205206
Observer.Create<(int Offset, int PageSize, IDisposable[] PreviousPage, IDisposable[] Page)>(_ => { }));
@@ -213,12 +214,12 @@ internal override AsyncPageBase<IDisposable> PageWithDisposablePlaceholder(IDisp
213214
0,
214215
1,
215216
Disposable.Empty,
216-
async (offset, pageSize, _) =>
217+
async (_, _, ct) =>
217218
{
218-
await Task.Delay(10);
219+
await Task.Delay(10, ct).ConfigureAwait(false);
219220
return new[] { Disposable.Empty };
220221
},
221-
(_, __) => disposable,
222+
(_, _) => disposable,
222223
new ImmediateAsyncPageFetchScheduler(),
223224
DefaultScheduler.Instance,
224225
Observer.Create<(int Offset, int PageSize, IDisposable[] PreviousPage, IDisposable[] Page)>(_ => { }));

0 commit comments

Comments
 (0)