<PackageReference Include="NUnit" Version="4.1.0" />

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.Runtime.CompilerServices; namespace NUnit.Framework.Constraints { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class DelayedConstraint : PrefixConstraint { [System.Runtime.CompilerServices.Nullable(0)] public class WithRawDelayInterval : DelayedConstraint { private readonly DelayedConstraint _parent; public WithDimensionedDelayInterval Minutes { get { _parent.DelayInterval = _parent.DelayInterval.InMinutes; return new WithDimensionedDelayInterval(_parent); } } public WithDimensionedDelayInterval Seconds { get { base.DelayInterval = base.DelayInterval.InSeconds; return new WithDimensionedDelayInterval(_parent); } } public WithDimensionedDelayInterval MilliSeconds { get { base.DelayInterval = base.DelayInterval.InMilliseconds; return new WithDimensionedDelayInterval(_parent); } } public WithRawDelayInterval(DelayedConstraint parent) : base(parent.BaseConstraint, parent.DelayInterval, parent.PollingInterval) { base.DelayInterval = parent.DelayInterval; _parent = parent; } public WithRawPollingInterval PollEvery(int milliSeconds) { if (milliSeconds < 0) throw new ArgumentException("Interval cannot be negative"); _parent.PollingInterval = new Interval(milliSeconds).InMilliseconds; return new WithRawPollingInterval(_parent); } } [System.Runtime.CompilerServices.Nullable(0)] public class WithDimensionedDelayInterval : DelayedConstraint { private readonly DelayedConstraint _parent; public WithDimensionedDelayInterval(DelayedConstraint parent) : base(parent.BaseConstraint, parent.DelayInterval, parent.PollingInterval) { base.DelayInterval = parent.DelayInterval; _parent = parent; } public WithRawPollingInterval PollEvery(int milliSeconds) { if (milliSeconds < 0) throw new ArgumentException("Interval cannot be negative"); _parent.PollingInterval = new Interval(milliSeconds).InMilliseconds; return new WithRawPollingInterval(_parent); } } [System.Runtime.CompilerServices.Nullable(0)] public class WithRawPollingInterval : DelayedConstraint { private readonly DelayedConstraint _parent; public DelayedConstraint Minutes { get { _parent.PollingInterval = _parent.PollingInterval.InMinutes; return _parent; } } public DelayedConstraint Seconds { get { _parent.PollingInterval = _parent.PollingInterval.InSeconds; return _parent; } } public DelayedConstraint MilliSeconds { get { _parent.PollingInterval = _parent.PollingInterval.InMilliseconds; return _parent; } } public WithRawPollingInterval(DelayedConstraint parent) : base(parent.BaseConstraint, parent.DelayInterval, parent.PollingInterval) { _parent = parent; } } [System.Runtime.CompilerServices.Nullable(0)] private class DelegatingConstraintResult : ConstraintResult { private readonly ConstraintResult _innerResult; public DelegatingConstraintResult(IConstraint constraint, ConstraintResult innerResult) : base(constraint, innerResult.ActualValue, innerResult.Status) { _innerResult = innerResult; } public override void WriteActualValueTo(MessageWriter writer) { _innerResult.WriteActualValueTo(writer); } public override void WriteAdditionalLinesTo(MessageWriter writer) { _innerResult.WriteAdditionalLinesTo(writer); } } protected Interval DelayInterval { get; set; } protected Interval PollingInterval { get; set; } public override string Description { get { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(13, 2); defaultInterpolatedStringHandler.AppendFormatted(base.BaseConstraint.Description); defaultInterpolatedStringHandler.AppendLiteral(" after "); defaultInterpolatedStringHandler.AppendFormatted(DelayInterval); defaultInterpolatedStringHandler.AppendLiteral(" delay"); return defaultInterpolatedStringHandler.ToStringAndClear(); } } public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds) : this(baseConstraint, delayInMilliseconds, 0) { } public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds, int pollingIntervalInMilliseconds) : base(baseConstraint, string.Empty) { if (delayInMilliseconds < 0) throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds"); if (pollingIntervalInMilliseconds < 0) throw new ArgumentException("Interval cannot be negative", "pollingIntervalInMilliseconds"); DelayInterval = new Interval(delayInMilliseconds).InMilliseconds; PollingInterval = new Interval(pollingIntervalInMilliseconds).InMilliseconds; } private DelayedConstraint(IConstraint baseConstraint, Interval delayInterval, Interval pollingInterval) : base(baseConstraint, string.Empty) { DelayInterval = delayInterval; PollingInterval = pollingInterval; } public override ConstraintResult ApplyTo<[System.Runtime.CompilerServices.Nullable(2)] TActual>(TActual actual) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, DelayInterval.AsTimeSpan); TimeSpan timeSpan; if (PollingInterval.IsNotZero) { while ((timestamp = Stopwatch.GetTimestamp()) < num) { long num2 = TimestampOffset(timestamp, PollingInterval.AsTimeSpan); timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); ConstraintResult constraintResult = base.BaseConstraint.ApplyTo(actual); if (constraintResult.IsSuccess) return new DelegatingConstraintResult(this, constraintResult); } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); } return new DelegatingConstraintResult(this, base.BaseConstraint.ApplyTo(actual)); } public override ConstraintResult ApplyTo<[System.Runtime.CompilerServices.Nullable(2)] TActual>(ActualValueDelegate<TActual> del) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, DelayInterval.AsTimeSpan); TimeSpan timeSpan; object actual; if (PollingInterval.IsNotZero) { long num2 = TimestampOffset(timestamp, PollingInterval.AsTimeSpan); while ((timestamp = Stopwatch.GetTimestamp()) < num) { if (num2 > timestamp) { timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); } num2 = TimestampOffset(timestamp, PollingInterval.AsTimeSpan); actual = InvokeDelegate(del); try { ConstraintResult constraintResult = base.BaseConstraint.ApplyTo(actual); if (constraintResult.IsSuccess) return new DelegatingConstraintResult(this, constraintResult); } catch (Exception) { } } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); } actual = InvokeDelegate(del); return new DelegatingConstraintResult(this, base.BaseConstraint.ApplyTo(actual)); } public override ConstraintResult ApplyTo<[System.Runtime.CompilerServices.Nullable(2)] TActual>(ref TActual actual) { long timestamp = Stopwatch.GetTimestamp(); long num = TimestampOffset(timestamp, DelayInterval.AsTimeSpan); TimeSpan timeSpan; if (PollingInterval.IsNotZero) { long num2 = TimestampOffset(timestamp, PollingInterval.AsTimeSpan); while ((timestamp = Stopwatch.GetTimestamp()) < num) { if (num2 > timestamp) { timeSpan = TimestampDiff((num < num2) ? num : num2, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); } num2 = TimestampOffset(timestamp, PollingInterval.AsTimeSpan); try { ConstraintResult constraintResult = base.BaseConstraint.ApplyTo(actual); if (constraintResult.IsSuccess) return new DelegatingConstraintResult(this, constraintResult); } catch (Exception) { } } } if ((timestamp = Stopwatch.GetTimestamp()) < num) { timeSpan = TimestampDiff(num, timestamp); ThreadUtility.BlockingDelay((int)timeSpan.TotalMilliseconds); } return new DelegatingConstraintResult(this, base.BaseConstraint.ApplyTo(actual)); } [System.Runtime.CompilerServices.NullableContext(2)] private static object InvokeDelegate<T>([System.Runtime.CompilerServices.Nullable(1)] ActualValueDelegate<T> del) { if (AsyncToSyncAdapter.IsAsyncOperation(del)) return AsyncToSyncAdapter.Await(() => del()); return del(); } protected override string GetStringRepresentation() { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(9, 2); defaultInterpolatedStringHandler.AppendLiteral("<after "); defaultInterpolatedStringHandler.AppendFormatted(DelayInterval.AsTimeSpan.TotalMilliseconds); defaultInterpolatedStringHandler.AppendLiteral(" "); defaultInterpolatedStringHandler.AppendFormatted(base.BaseConstraint); defaultInterpolatedStringHandler.AppendLiteral(">"); return defaultInterpolatedStringHandler.ToStringAndClear(); } 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); } } }