[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Constraints / Numerics.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 using System;
30
31 namespace NUnit.Framework.Constraints
32 {
33     /// <summary>
34     /// The Numerics class contains common operations on numeric _values.
35     /// </summary>
36     public class Numerics
37     {
38         #region Numeric Type Recognition
39         /// <summary>
40         /// Checks the type of the object, returning true if
41         /// the object is a numeric type.
42         /// </summary>
43         /// <param name="obj">The object to check</param>
44         /// <returns>true if the object is a numeric type</returns>
45         public static bool IsNumericType(Object obj)
46         {
47             return IsFloatingPointNumeric(obj) || IsFixedPointNumeric(obj);
48         }
49
50         /// <summary>
51         /// Checks the type of the object, returning true if
52         /// the object is a floating point numeric type.
53         /// </summary>
54         /// <param name="obj">The object to check</param>
55         /// <returns>true if the object is a floating point numeric type</returns>
56         public static bool IsFloatingPointNumeric(Object obj)
57         {
58             if (null != obj)
59             {
60                 if (obj is System.Double) return true;
61                 if (obj is System.Single) return true;
62             }
63             return false;
64         }
65         /// <summary>
66         /// Checks the type of the object, returning true if
67         /// the object is a fixed point numeric type.
68         /// </summary>
69         /// <param name="obj">The object to check</param>
70         /// <returns>true if the object is a fixed point numeric type</returns>
71         public static bool IsFixedPointNumeric(Object obj)
72         {
73             if (null != obj)
74             {
75                 if (obj is System.Byte) return true;
76                 if (obj is System.SByte) return true;
77                 if (obj is System.Decimal) return true;
78                 if (obj is System.Int32) return true;
79                 if (obj is System.UInt32) return true;
80                 if (obj is System.Int64) return true;
81                 if (obj is System.UInt64) return true;
82                 if (obj is System.Int16) return true;
83                 if (obj is System.UInt16) return true;
84                 if (obj is System.Char) return true;
85             }
86             return false;
87         }
88         #endregion
89
90         #region Numeric Equality
91         /// <summary>
92         /// Test two numeric _values for equality, performing the usual numeric 
93         /// conversions and using a provided or default tolerance. If the tolerance 
94         /// provided is Empty, this method may set it to a default tolerance.
95         /// </summary>
96         /// <param name="expected">The expected value</param>
97         /// <param name="actual">The actual value</param>
98         /// <param name="tolerance">A reference to the tolerance in effect</param>
99         /// <returns>True if the _values are equal</returns>
100         public static bool AreEqual(object expected, object actual, ref Tolerance tolerance)
101         {
102             if (expected is double || actual is double)
103                 return AreEqual(Convert.ToDouble(expected), Convert.ToDouble(actual), ref tolerance);
104
105             if (expected is float || actual is float)
106                 return AreEqual(Convert.ToSingle(expected), Convert.ToSingle(actual), ref tolerance);
107
108             if (tolerance.Mode == ToleranceMode.Ulps)
109                 throw new InvalidOperationException("Ulps may only be specified for floating point arguments");
110
111             if (expected is decimal || actual is decimal)
112                 return AreEqual(Convert.ToDecimal(expected), Convert.ToDecimal(actual), tolerance);
113
114             if (expected is ulong || actual is ulong)
115                 return AreEqual(Convert.ToUInt64(expected), Convert.ToUInt64(actual), tolerance);
116
117             if (expected is long || actual is long)
118                 return AreEqual(Convert.ToInt64(expected), Convert.ToInt64(actual), tolerance);
119
120             if (expected is uint || actual is uint)
121                 return AreEqual(Convert.ToUInt32(expected), Convert.ToUInt32(actual), tolerance);
122
123             return AreEqual(Convert.ToInt32(expected), Convert.ToInt32(actual), tolerance);
124         }
125
126         private static bool AreEqual(double expected, double actual, ref Tolerance tolerance)
127         {
128             if (double.IsNaN(expected) && double.IsNaN(actual))
129                 return true;
130
131             // Handle infinity specially since subtracting two infinite _values gives 
132             // NaN and the following test fails. mono also needs NaN to be handled
133             // specially although ms.net could use either method. Also, handle
134             // situation where no tolerance is used.
135             if (double.IsInfinity(expected) || double.IsNaN(expected) || double.IsNaN(actual))
136             {
137                 return expected.Equals(actual);
138             }
139
140             if (tolerance.IsUnsetOrDefault && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
141                 tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
142
143             switch (tolerance.Mode)
144             {
145                 case ToleranceMode.Unset:
146                     return expected.Equals(actual);
147
148                 case ToleranceMode.Linear:
149                     return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
150
151                 case ToleranceMode.Percent:
152                     if (expected == 0.0)
153                         return expected.Equals(actual);
154
155                     double relativeError = Math.Abs((expected - actual) / expected);
156                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
157
158                 case ToleranceMode.Ulps:
159                     return FloatingPointNumerics.AreAlmostEqualUlps(
160                         expected, actual, Convert.ToInt64(tolerance.Value));
161
162                 default:
163                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
164             }
165         }
166
167         private static bool AreEqual(float expected, float actual, ref Tolerance tolerance)
168         {
169             if (float.IsNaN(expected) && float.IsNaN(actual))
170                 return true;
171
172             // handle infinity specially since subtracting two infinite _values gives 
173             // NaN and the following test fails. mono also needs NaN to be handled
174             // specially although ms.net could use either method.
175             if (float.IsInfinity(expected) || float.IsNaN(expected) || float.IsNaN(actual))
176             {
177                 return expected.Equals(actual);
178             }
179
180             if (tolerance.IsUnsetOrDefault && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
181                 tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
182
183             switch (tolerance.Mode)
184             {
185                 case ToleranceMode.Unset:
186                     return expected.Equals(actual);
187
188                 case ToleranceMode.Linear:
189                     return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
190
191                 case ToleranceMode.Percent:
192                     if (expected == 0.0f)
193                         return expected.Equals(actual);
194                     float relativeError = Math.Abs((expected - actual) / expected);
195                     return (relativeError <= Convert.ToSingle(tolerance.Value) / 100.0f);
196
197                 case ToleranceMode.Ulps:
198                     return FloatingPointNumerics.AreAlmostEqualUlps(
199                         expected, actual, Convert.ToInt32(tolerance.Value));
200
201                 default:
202                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
203             }
204         }
205
206
207         private static bool AreEqual(decimal expected, decimal actual, Tolerance tolerance)
208         {
209             switch (tolerance.Mode)
210             {
211                 case ToleranceMode.Unset:
212                     return expected.Equals(actual);
213
214                 case ToleranceMode.Linear:
215                     decimal decimalTolerance = Convert.ToDecimal(tolerance.Value);
216                     if (decimalTolerance > 0m)
217                         return Math.Abs(expected - actual) <= decimalTolerance;
218
219                     return expected.Equals(actual);
220
221                 case ToleranceMode.Percent:
222                     if (expected == 0m)
223                         return expected.Equals(actual);
224
225                     double relativeError = Math.Abs(
226                         (double)(expected - actual) / (double)expected);
227                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
228
229                 default:
230                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
231             }
232         }
233
234         private static bool AreEqual(ulong expected, ulong actual, Tolerance tolerance)
235         {
236             switch (tolerance.Mode)
237             {
238                 case ToleranceMode.Unset:
239                     return expected.Equals(actual);
240
241                 case ToleranceMode.Linear:
242                     ulong ulongTolerance = Convert.ToUInt64(tolerance.Value);
243                     if (ulongTolerance > 0ul)
244                     {
245                         ulong diff = expected >= actual ? expected - actual : actual - expected;
246                         return diff <= ulongTolerance;
247                     }
248
249                     return expected.Equals(actual);
250
251                 case ToleranceMode.Percent:
252                     if (expected == 0ul)
253                         return expected.Equals(actual);
254
255                     // Can't do a simple Math.Abs() here since it's unsigned
256                     ulong difference = Math.Max(expected, actual) - Math.Min(expected, actual);
257                     double relativeError = Math.Abs((double)difference / (double)expected);
258                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
259
260                 default:
261                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
262             }
263         }
264
265         private static bool AreEqual(long expected, long actual, Tolerance tolerance)
266         {
267             switch (tolerance.Mode)
268             {
269                 case ToleranceMode.Unset:
270                     return expected.Equals(actual);
271
272                 case ToleranceMode.Linear:
273                     long longTolerance = Convert.ToInt64(tolerance.Value);
274                     if (longTolerance > 0L)
275                         return Math.Abs(expected - actual) <= longTolerance;
276
277                     return expected.Equals(actual);
278
279                 case ToleranceMode.Percent:
280                     if (expected == 0L)
281                         return expected.Equals(actual);
282
283                     double relativeError = Math.Abs(
284                         (double)(expected - actual) / (double)expected);
285                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
286
287                 default:
288                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
289             }
290         }
291
292         private static bool AreEqual(uint expected, uint actual, Tolerance tolerance)
293         {
294             switch (tolerance.Mode)
295             {
296                 case ToleranceMode.Unset:
297                     return expected.Equals(actual);
298
299                 case ToleranceMode.Linear:
300                     uint uintTolerance = Convert.ToUInt32(tolerance.Value);
301                     if (uintTolerance > 0)
302                     {
303                         uint diff = expected >= actual ? expected - actual : actual - expected;
304                         return diff <= uintTolerance;
305                     }
306
307                     return expected.Equals(actual);
308
309                 case ToleranceMode.Percent:
310                     if (expected == 0u)
311                         return expected.Equals(actual);
312
313                     // Can't do a simple Math.Abs() here since it's unsigned
314                     uint difference = Math.Max(expected, actual) - Math.Min(expected, actual);
315                     double relativeError = Math.Abs((double)difference / (double)expected);
316                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
317
318                 default:
319                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
320             }
321         }
322
323         private static bool AreEqual(int expected, int actual, Tolerance tolerance)
324         {
325             switch (tolerance.Mode)
326             {
327                 case ToleranceMode.Unset:
328                     return expected.Equals(actual);
329
330                 case ToleranceMode.Linear:
331                     int intTolerance = Convert.ToInt32(tolerance.Value);
332                     if (intTolerance > 0)
333                         return Math.Abs(expected - actual) <= intTolerance;
334
335                     return expected.Equals(actual);
336
337                 case ToleranceMode.Percent:
338                     if (expected == 0)
339                         return expected.Equals(actual);
340
341                     double relativeError = Math.Abs(
342                         (double)(expected - actual) / (double)expected);
343                     return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
344
345                 default:
346                     throw new ArgumentException("Unknown tolerance mode specified", "mode");
347             }
348         }
349         #endregion
350
351         #region Numeric Comparisons
352         /// <summary>
353         /// Compare two numeric _values, performing the usual numeric conversions.
354         /// </summary>
355         /// <param name="expected">The expected value</param>
356         /// <param name="actual">The actual value</param>
357         /// <returns>The relationship of the _values to each other</returns>
358         public static int Compare(object expected, object actual)
359         {
360             if (!IsNumericType(expected) || !IsNumericType(actual))
361                 throw new ArgumentException("Both arguments must be numeric");
362
363             if (IsFloatingPointNumeric(expected) || IsFloatingPointNumeric(actual))
364                 return Convert.ToDouble(expected).CompareTo(Convert.ToDouble(actual));
365
366             if (expected is decimal || actual is decimal)
367                 return Convert.ToDecimal(expected).CompareTo(Convert.ToDecimal(actual));
368
369             if (expected is ulong || actual is ulong)
370                 return Convert.ToUInt64(expected).CompareTo(Convert.ToUInt64(actual));
371
372             if (expected is long || actual is long)
373                 return Convert.ToInt64(expected).CompareTo(Convert.ToInt64(actual));
374
375             if (expected is uint || actual is uint)
376                 return Convert.ToUInt32(expected).CompareTo(Convert.ToUInt32(actual));
377
378             return Convert.ToInt32(expected).CompareTo(Convert.ToInt32(actual));
379         }
380         #endregion
381
382         private Numerics()
383         {
384         }
385     }
386 }