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);
}
}
}