/src/NUnit/framework/Constraints/DelayedConstraint.cs
C# | 162 lines | 90 code | 16 blank | 56 comment | 13 complexity | bc595c60e22e445a9f5768f674e19738 MD5 | raw file
1// **************************************************************** 2// Copyright 2008, Charlie Poole 3// This is free software licensed under the NUnit license. You may 4// obtain a copy of the license at http://nunit.org 5// **************************************************************** 6using System; 7using System.Threading; 8 9namespace NUnit.Framework.Constraints 10{ 11 ///<summary> 12 /// Applies a delay to the match so that a match can be evaluated in the future. 13 ///</summary> 14 public class DelayedConstraint : PrefixConstraint 15 { 16 private readonly int delayInMilliseconds; 17 private readonly int pollingInterval; 18 19 ///<summary> 20 /// Creates a new DelayedConstraint 21 ///</summary> 22 ///<param name="baseConstraint">The inner constraint two decorate</param> 23 ///<param name="delayInMilliseconds">The time interval after which the match is performed</param> 24 ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception> 25 public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds) 26 : this(baseConstraint, delayInMilliseconds, 0) { } 27 28 ///<summary> 29 /// Creates a new DelayedConstraint 30 ///</summary> 31 ///<param name="baseConstraint">The inner constraint two decorate</param> 32 ///<param name="delayInMilliseconds">The time interval after which the match is performed</param> 33 ///<param name="pollingInterval">The time interval used for polling</param> 34 ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception> 35 public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds, int pollingInterval) 36 : base(baseConstraint) 37 { 38 if (delayInMilliseconds < 0) 39 throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds"); 40 41 this.delayInMilliseconds = delayInMilliseconds; 42 this.pollingInterval = pollingInterval; 43 } 44 45 /// <summary> 46 /// Test whether the constraint is satisfied by a given value 47 /// </summary> 48 /// <param name="actual">The value to be tested</param> 49 /// <returns>True for if the base constraint fails, false if it succeeds</returns> 50 public override bool Matches(object actual) 51 { 52 Thread.Sleep(delayInMilliseconds); 53 this.actual = actual; 54 return baseConstraint.Matches(actual); 55 } 56 57 /// <summary> 58 /// Test whether the constraint is satisfied by a delegate 59 /// </summary> 60 /// <param name="del">The delegate whose value is to be tested</param> 61 /// <returns>True for if the base constraint fails, false if it succeeds</returns> 62 public override bool Matches(ActualValueDelegate del) 63 { 64 int remainingDelay = delayInMilliseconds; 65 66 while (pollingInterval > 0 && pollingInterval < remainingDelay) 67 { 68 remainingDelay -= pollingInterval; 69 Thread.Sleep(pollingInterval); 70 this.actual = del(); 71 if (baseConstraint.Matches(actual)) 72 return true; 73 } 74 75 if ( remainingDelay > 0 ) 76 Thread.Sleep(remainingDelay); 77 this.actual = del(); 78 return baseConstraint.Matches(actual); 79 } 80 81#if NET_2_0 82 /// <summary> 83 /// Test whether the constraint is satisfied by a given reference. 84 /// Overridden to wait for the specified delay period before 85 /// calling the base constraint with the dereferenced value. 86 /// </summary> 87 /// <param name="actual">A reference to the value to be tested</param> 88 /// <returns>True for success, false for failure</returns> 89 public override bool Matches<T>(ref T actual) 90 { 91 int remainingDelay = delayInMilliseconds; 92 93 while (pollingInterval > 0 && pollingInterval < remainingDelay) 94 { 95 remainingDelay -= pollingInterval; 96 Thread.Sleep(pollingInterval); 97 this.actual = actual; 98 if (baseConstraint.Matches(actual)) 99 return true; 100 } 101 102 if ( remainingDelay > 0 ) 103 Thread.Sleep(remainingDelay); 104 this.actual = actual; 105 return baseConstraint.Matches(actual); 106 } 107#else 108 /// <summary> 109 /// Test whether the constraint is satisfied by a given boolean reference. 110 /// Overridden to wait for the specified delay period before 111 /// calling the base constraint with the dereferenced value. 112 /// </summary> 113 /// <param name="actual">A reference to the value to be tested</param> 114 /// <returns>True for success, false for failure</returns> 115 public override bool Matches(ref bool actual) 116 { 117 int remainingDelay = delayInMilliseconds; 118 119 while (pollingInterval > 0 && pollingInterval < remainingDelay) 120 { 121 remainingDelay -= pollingInterval; 122 Thread.Sleep(pollingInterval); 123 this.actual = actual; 124 if (baseConstraint.Matches(actual)) 125 return true; 126 } 127 128 if ( remainingDelay > 0 ) 129 Thread.Sleep(remainingDelay); 130 this.actual = actual; 131 return baseConstraint.Matches(actual); 132 } 133#endif 134 135 /// <summary> 136 /// Write the constraint description to a MessageWriter 137 /// </summary> 138 /// <param name="writer">The writer on which the description is displayed</param> 139 public override void WriteDescriptionTo(MessageWriter writer) 140 { 141 baseConstraint.WriteDescriptionTo(writer); 142 writer.Write(string.Format(" after {0} millisecond delay", delayInMilliseconds)); 143 } 144 145 /// <summary> 146 /// Write the actual value for a failing constraint test to a MessageWriter. 147 /// </summary> 148 /// <param name="writer">The writer on which the actual value is displayed</param> 149 public override void WriteActualValueTo(MessageWriter writer) 150 { 151 baseConstraint.WriteActualValueTo(writer); 152 } 153 154 /// <summary> 155 /// Returns the string representation of the constraint. 156 /// </summary> 157 protected override string GetStringRepresentation() 158 { 159 return string.Format("<after {0} {1}>", delayInMilliseconds, baseConstraint); 160 } 161 } 162}