<PackageReference Include="NUnit" Version="3.0.0-beta-2" />

DelayedConstraint

Applies a delay to the match so that a match can be evaluated in the future.
using NUnit.Framework.Internal; using System; using System.Diagnostics; using System.Threading; namespace NUnit.Framework.Constraints { public class DelayedConstraint : PrefixConstraint { private readonly int delayInMilliseconds; private readonly int pollingInterval; public override string Description => $"{baseConstraint.Description}""{delayInMilliseconds}"""; public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds) : this(baseConstraint, delayInMilliseconds, 0) { } public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds, int pollingInterval) : base(baseConstraint) { if (delayInMilliseconds < 0) throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds"); this.delayInMilliseconds = delayInMilliseconds; this.pollingInterval = pollingInterval; } public override ConstraintResult ApplyTo<TActual>(TActual actual) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)delayInMilliseconds)); TimeSpan timeSpan; if (pollingInterval > 0) { long num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); while ((timestamp = Stopwatch.GetTimestamp()) < num) { if (num2 > timestamp) { timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); if (baseConstraint.ApplyTo(actual).IsSuccess) return new ConstraintResult(this, actual, true); } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } return new ConstraintResult(this, actual, baseConstraint.ApplyTo(actual).IsSuccess); } public override ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> del) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)delayInMilliseconds)); TimeSpan timeSpan; object obj; if (pollingInterval > 0) { long num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); while ((timestamp = Stopwatch.GetTimestamp()) < num) { if (num2 > timestamp) { timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); obj = InvokeDelegate(del); try { if (baseConstraint.ApplyTo(obj).IsSuccess) return new ConstraintResult(this, obj, true); } catch (Exception) { } } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } obj = InvokeDelegate(del); return new ConstraintResult(this, obj, baseConstraint.ApplyTo(obj).IsSuccess); } private static object InvokeDelegate<T>(ActualValueDelegate<T> del) { if (AsyncInvocationRegion.IsAsyncOperation(del)) { using (AsyncInvocationRegion asyncInvocationRegion = AsyncInvocationRegion.Create(del)) { return asyncInvocationRegion.WaitForPendingOperationsToComplete(del()); } } return del(); } public override ConstraintResult ApplyTo<TActual>(ref TActual actual) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)delayInMilliseconds)); TimeSpan timeSpan; if (pollingInterval > 0) { long num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); while ((timestamp = Stopwatch.GetTimestamp()) < num) { if (num2 > timestamp) { timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } num2 = TimestampOffset(timestamp, TimeSpan.FromMilliseconds((double)pollingInterval)); try { if (baseConstraint.ApplyTo(actual).IsSuccess) return new ConstraintResult(this, actual, true); } catch (Exception) { } } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); Thread.Sleep((int)timeSpan.TotalMilliseconds); } return new ConstraintResult(this, actual, baseConstraint.ApplyTo(actual).IsSuccess); } protected override string GetStringRepresentation() { return $"""{delayInMilliseconds}""{baseConstraint}"""; } private static long TimestampOffset(long timestamp, TimeSpan offset) { return timestamp + (long)(offset.TotalSeconds * (double)Stopwatch.Frequency); } private static TimeSpan TimestampDiff(long timestamp1, long timestamp2) { return TimeSpan.FromSeconds((double)(timestamp1 - timestamp2) / (double)Stopwatch.Frequency); } } }