Skip to content

Commit 0928fb1

Browse files
authored
Merge pull request nunit#4815 from Dreamescaper/make_delayed_work_with_throws
Make DelayedConstraint work with ThrowsContraint
2 parents b8ef8b5 + 49bdfa1 commit 0928fb1

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

src/NUnitFramework/framework/Constraints/DelayedConstraint.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ public override ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> d
258258
long now = Stopwatch.GetTimestamp();
259259
long delayEnd = TimestampOffset(now, DelayInterval.AsTimeSpan);
260260

261-
object? actual;
262261
if (PollingInterval.IsNotZero)
263262
{
264263
long nextPoll = TimestampOffset(now, PollingInterval.AsTimeSpan);
@@ -268,11 +267,9 @@ public override ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> d
268267
ThreadUtility.BlockingDelay((int)TimestampDiff(delayEnd < nextPoll ? delayEnd : nextPoll, now).TotalMilliseconds);
269268
nextPoll = TimestampOffset(now, PollingInterval.AsTimeSpan);
270269

271-
actual = InvokeDelegate(del);
272-
273270
try
274271
{
275-
ConstraintResult result = BaseConstraint.ApplyTo(actual);
272+
ConstraintResult result = BaseConstraint.ApplyTo(del);
276273
if (result.IsSuccess)
277274
return new DelegatingConstraintResult(this, result);
278275
}
@@ -285,8 +282,7 @@ public override ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> d
285282
if ((now = Stopwatch.GetTimestamp()) < delayEnd)
286283
ThreadUtility.BlockingDelay((int)TimestampDiff(delayEnd, now).TotalMilliseconds);
287284

288-
actual = InvokeDelegate(del);
289-
return new DelegatingConstraintResult(this, BaseConstraint.ApplyTo(actual));
285+
return new DelegatingConstraintResult(this, BaseConstraint.ApplyTo(del));
290286
}
291287

292288
/// <summary>

src/NUnitFramework/tests/Constraints/DelayedConstraintTests.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,53 @@ public void ThatPollingCallsDelegateCorrectNumberOfTimes()
241241
Assert.That(PollCount, Is.EqualTo(4).After(110, 25));
242242
}
243243

244+
[Test]
245+
public void AssertionExpectingAnExceptionWithRetrySucceeds()
246+
{
247+
int i = 0;
248+
void ThrowsAfterRetry()
249+
{
250+
if (i++ > 3)
251+
{
252+
throw new InvalidOperationException("Always throws after third attempt.");
253+
}
254+
}
255+
256+
Assert.That(ThrowsAfterRetry, Throws.InvalidOperationException.After(AFTER, POLLING));
257+
}
258+
259+
[Test]
260+
public void AssertionExpectingNoExceptionWithRetrySucceeds()
261+
{
262+
int i = 0;
263+
void DoesNotThrowAfterRetry()
264+
{
265+
if (i++ < 3)
266+
{
267+
throw new InvalidOperationException("Only throws before third attempt.");
268+
}
269+
}
270+
271+
Assert.That(DoesNotThrowAfterRetry, Throws.Nothing.After(AFTER, POLLING));
272+
}
273+
274+
[Test]
275+
public void AssertionForDelegateWhichThrowsExceptionUntilRetriedSucceeds()
276+
{
277+
int i = 0;
278+
string DoesNotThrowAfterRetry()
279+
{
280+
if (i++ < 3)
281+
{
282+
throw new InvalidOperationException("Only throws before third attempt.");
283+
}
284+
285+
return "Success!";
286+
}
287+
288+
Assert.That(DoesNotThrowAfterRetry, Is.EqualTo("Success!").After(AFTER, POLLING));
289+
}
290+
244291
private int PollCount()
245292
{
246293
return _pollCount++;
@@ -280,7 +327,8 @@ private static object MethodReturningZero()
280327

281328
private static readonly AutoResetEvent WaitEvent = new AutoResetEvent(false);
282329

283-
[OneTimeTearDown] public void OneTimeTearDown()
330+
[OneTimeTearDown]
331+
public void OneTimeTearDown()
284332
{
285333
WaitEvent.Dispose();
286334
}

0 commit comments

Comments
 (0)