[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Constraints / DelayedConstraint.cs
1 // ***********************************************************************
2 // Copyright (c) 2008 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 #if !PORTABLE
30 using System;
31 using System.Diagnostics;
32 using System.Threading;
33 using NUnit.Compatibility;
34 using NUnit.Framework.Internal;
35
36 namespace NUnit.Framework.Constraints
37 {
38     ///<summary>
39     /// Applies a delay to the match so that a match can be evaluated in the future.
40     ///</summary>
41     public class DelayedConstraint : PrefixConstraint
42     {
43         // TODO: Needs error message tests
44
45         private readonly int delayInMilliseconds;
46         private readonly int pollingInterval;
47
48         ///<summary>
49         /// Creates a new DelayedConstraint
50         ///</summary>
51         ///<param name="baseConstraint">The inner constraint to decorate</param>
52         ///<param name="delayInMilliseconds">The time interval after which the match is performed</param>
53         ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
54         public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds)
55             : this(baseConstraint, delayInMilliseconds, 0) { }
56
57         ///<summary>
58         /// Creates a new DelayedConstraint
59         ///</summary>
60         ///<param name="baseConstraint">The inner constraint to decorate</param>
61         ///<param name="delayInMilliseconds">The time interval after which the match is performed, in milliseconds</param>
62         ///<param name="pollingInterval">The time interval used for polling, in milliseconds</param>
63         ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
64         public DelayedConstraint(IConstraint baseConstraint, int delayInMilliseconds, int pollingInterval)
65             : base(baseConstraint)
66         {
67             if (delayInMilliseconds < 0)
68                 throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds");
69
70             this.delayInMilliseconds = delayInMilliseconds;
71             this.pollingInterval = pollingInterval;
72         }
73
74         /// <summary>
75         /// Gets text describing a constraint
76         /// </summary>
77         public override string Description
78         {
79             get { return string.Format("{0} after {1} millisecond delay", BaseConstraint.Description, delayInMilliseconds); }
80         }
81
82         /// <summary>
83         /// Test whether the constraint is satisfied by a given value
84         /// </summary>
85         /// <param name="actual">The value to be tested</param>
86         /// <returns>True for if the base constraint fails, false if it succeeds</returns>
87         public override ConstraintResult ApplyTo<TActual>(TActual actual)
88         {
89             long now = Stopwatch.GetTimestamp();
90             long delayEnd = TimestampOffset(now, TimeSpan.FromMilliseconds(delayInMilliseconds));
91
92             if (pollingInterval > 0)
93             {
94                 long nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
95                 while ((now = Stopwatch.GetTimestamp()) < delayEnd)
96                 {
97                     if (nextPoll > now)
98                         Thread.Sleep((int)TimestampDiff(delayEnd < nextPoll ? delayEnd : nextPoll, now).TotalMilliseconds);
99                     nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
100
101                     ConstraintResult result = BaseConstraint.ApplyTo(actual);
102                     if (result.IsSuccess)
103                         return new ConstraintResult(this, actual, true);
104                 }
105             }
106             if ((now = Stopwatch.GetTimestamp()) < delayEnd)
107                 Thread.Sleep((int)TimestampDiff(delayEnd, now).TotalMilliseconds);
108
109             return new ConstraintResult(this, actual, BaseConstraint.ApplyTo(actual).IsSuccess);
110         }
111
112         /// <summary>
113         /// Test whether the constraint is satisfied by a delegate
114         /// </summary>
115         /// <param name="del">The delegate whose value is to be tested</param>
116         /// <returns>A ConstraintResult</returns>
117         public override ConstraintResult ApplyTo<TActual>(ActualValueDelegate<TActual> del)
118         {
119             long now = Stopwatch.GetTimestamp();
120             long delayEnd = TimestampOffset(now, TimeSpan.FromMilliseconds(delayInMilliseconds));
121
122             object actual;
123             if (pollingInterval > 0)
124             {
125                 long nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
126                 while ((now = Stopwatch.GetTimestamp()) < delayEnd)
127                 {
128                     if (nextPoll > now)
129                         Thread.Sleep((int)TimestampDiff(delayEnd < nextPoll ? delayEnd : nextPoll, now).TotalMilliseconds);
130                     nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
131
132                     actual = InvokeDelegate(del);
133
134                     try
135                     {
136                         ConstraintResult result = BaseConstraint.ApplyTo(actual);
137                         if (result.IsSuccess)
138                             return new ConstraintResult(this, actual, true);
139                     }
140                     catch(Exception)
141                     {
142                         // Ignore any exceptions when polling
143                     }
144                 }
145             }
146             if ((now = Stopwatch.GetTimestamp()) < delayEnd)
147                 Thread.Sleep((int)TimestampDiff(delayEnd, now).TotalMilliseconds);
148
149             actual = InvokeDelegate(del);
150             return new ConstraintResult(this, actual, BaseConstraint.ApplyTo(actual).IsSuccess);
151         }
152
153         private static object InvokeDelegate<T>(ActualValueDelegate<T> del)
154         {
155 #if NET_4_0 || NET_4_5
156             if (AsyncInvocationRegion.IsAsyncOperation(del))
157                 using (AsyncInvocationRegion region = AsyncInvocationRegion.Create(del))
158                     return region.WaitForPendingOperationsToComplete(del());
159 #endif
160
161             return del();
162         }
163
164         /// <summary>
165         /// Test whether the constraint is satisfied by a given reference.
166         /// Overridden to wait for the specified delay period before
167         /// calling the base constraint with the dereferenced value.
168         /// </summary>
169         /// <param name="actual">A reference to the value to be tested</param>
170         /// <returns>True for success, false for failure</returns>
171         public override ConstraintResult ApplyTo<TActual>(ref TActual actual)
172         {
173             long now = Stopwatch.GetTimestamp();
174             long delayEnd = TimestampOffset(now, TimeSpan.FromMilliseconds(delayInMilliseconds));
175
176             if (pollingInterval > 0)
177             {
178                 long nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
179                 while ((now = Stopwatch.GetTimestamp()) < delayEnd)
180                 {
181                     if (nextPoll > now)
182                         Thread.Sleep((int)TimestampDiff(delayEnd < nextPoll ? delayEnd : nextPoll, now).TotalMilliseconds);
183                     nextPoll = TimestampOffset(now, TimeSpan.FromMilliseconds(pollingInterval));
184
185                     try
186                     {
187                         ConstraintResult result = BaseConstraint.ApplyTo(actual);
188                         if (result.IsSuccess)
189                             return new ConstraintResult(this, actual, true);
190                     }
191                     catch(Exception)
192                     {
193                         // Ignore any exceptions when polling
194                     }
195                 }
196             }
197             if ((now = Stopwatch.GetTimestamp()) < delayEnd)
198                 Thread.Sleep((int)TimestampDiff(delayEnd, now).TotalMilliseconds);
199
200             return new ConstraintResult(this, actual, BaseConstraint.ApplyTo(actual).IsSuccess);
201         }
202
203         /// <summary>
204         /// Returns the string representation of the constraint.
205         /// </summary>
206         protected override string GetStringRepresentation()
207         {
208             return string.Format("<after {0} {1}>", delayInMilliseconds, BaseConstraint);
209         }
210
211         /// <summary>
212         /// Adjusts a Timestamp by a given TimeSpan
213         /// </summary>
214         /// <param name="timestamp"></param>
215         /// <param name="offset"></param>
216         /// <returns></returns>
217         private static long TimestampOffset(long timestamp, TimeSpan offset)
218         {
219             return timestamp + (long)(offset.TotalSeconds * Stopwatch.Frequency);
220         }
221
222         /// <summary>
223         /// Returns the difference between two Timestamps as a TimeSpan
224         /// </summary>
225         /// <param name="timestamp1"></param>
226         /// <param name="timestamp2"></param>
227         /// <returns></returns>
228         private static TimeSpan TimestampDiff(long timestamp1, long timestamp2)
229         {
230             return TimeSpan.FromSeconds((double)(timestamp1 - timestamp2) / Stopwatch.Frequency);
231         }
232     }
233 }
234 #endif