Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace Wolfgang.Etl.TestKit.Xunit;
/// <item><description><c>CurrentItemCount</c> is incremented as items are yielded.</description></item>
/// <item><description><c>ReportingInterval</c> rejects values less than 1.</description></item>
/// <item><description><c>MaximumItemCount</c> stops extraction at the specified limit.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 0.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 1.</description></item>
/// <item><description><c>SkipItemCount</c> rejects values less than 0.</description></item>
/// <item><description>Progress callbacks fire at least once per extraction.</description></item>
/// <item><description><c>CreateProgressReport</c> reflects <c>CurrentItemCount</c>.</description></item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace Wolfgang.Etl.TestKit.Xunit;
/// <item><description><c>CurrentItemCount</c> is incremented as items are loaded.</description></item>
/// <item><description><c>ReportingInterval</c> rejects values less than 1.</description></item>
/// <item><description><c>MaximumItemCount</c> stops loading at the specified limit.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 0.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 1.</description></item>
/// <item><description><c>SkipItemCount</c> skips the specified number of items.</description></item>
/// <item><description><c>SkipItemCount</c> rejects values less than 0.</description></item>
/// <item><description>Progress callbacks fire when the timer fires.</description></item>
Expand Down
10 changes: 8 additions & 2 deletions src/Wolfgang.Etl.TestKit.Xunit/ManualProgressTimer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ namespace Wolfgang.Etl.TestKit.Xunit;
/// TProgress? captured = null;
/// var progress = new SynchronousProgress&lt;TProgress&gt;(r => captured = r);
///
/// var task = sut.ExtractAsync(progress).ToListAsync().AsTask();
/// // Begin enumeration and pull the first item so the pipeline is mid-flight,
/// // then fire the timer deterministically before draining the rest. This
/// // avoids the race where a fast synchronous source completes (and the
/// // timer's Elapsed handler is unsubscribed in the worker's finally) before
/// // Fire() is reached.
/// await using var enumerator = sut.ExtractAsync(progress).GetAsyncEnumerator();
/// await enumerator.MoveNextAsync();
/// timer.Fire();
/// await task;
/// while (await enumerator.MoveNextAsync()) { }
///
/// Assert.NotNull(captured);
/// </code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace Wolfgang.Etl.TestKit.Xunit;
/// <item><description><c>CurrentItemCount</c> is incremented as items are transformed.</description></item>
/// <item><description><c>ReportingInterval</c> rejects values less than 1.</description></item>
/// <item><description><c>MaximumItemCount</c> stops transformation at the specified limit.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 0.</description></item>
/// <item><description><c>MaximumItemCount</c> rejects values less than 1.</description></item>
/// <item><description><c>SkipItemCount</c> skips the specified number of items.</description></item>
/// <item><description><c>SkipItemCount</c> rejects values less than 0.</description></item>
/// <item><description>Progress callbacks fire when the timer fires.</description></item>
Expand Down
10 changes: 8 additions & 2 deletions src/Wolfgang.Etl.TestKit/TestExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ [EnumeratorCancellation] CancellationToken token
{
token.ThrowIfCancellationRequested();

// The wrapped source is synchronous, so this iterator would otherwise
// contain no await. Yield once up front to honour the async-iterator
// contract on every exit path (including the MaximumItemCount
// yield-break) and to give callers an asynchronous hop. Placing it here
// rather than after the loop keeps it reachable regardless of how the
// loop terminates.
await Task.Yield();

var enumerator = (_enumerator ?? _enumerable!.GetEnumerator())!;
var ownsEnumerator = _enumerator == null;

Expand Down Expand Up @@ -218,7 +226,5 @@ [EnumeratorCancellation] CancellationToken token
enumerator.Dispose();
}
}

await Task.Yield(); // satisfies async method contract without causing extra allocations
}
}
Loading