This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / nunit20 / framework / Assert.cs
1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
3 '
4 ' Copyright © 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright © 2000-2003 Philip A. Craig
6 '
7 ' This software is provided 'as-is', without any express or implied warranty. In no 
8 ' event will the authors be held liable for any damages arising from the use of this 
9 ' software.
10
11 ' Permission is granted to anyone to use this software for any purpose, including 
12 ' commercial applications, and to alter it and redistribute it freely, subject to the 
13 ' following restrictions:
14 '
15 ' 1. The origin of this software must not be misrepresented; you must not claim that 
16 ' you wrote the original software. If you use this software in a product, an 
17 ' acknowledgment (see the following) in the product documentation is required.
18 '
19 ' Portions Copyright © 2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright © 2000-2003 Philip A. Craig
21 '
22 ' 2. Altered source versions must be plainly marked as such, and must not be 
23 ' misrepresented as being the original software.
24 '
25 ' 3. This notice may not be removed or altered from any source distribution.
26 '
27 '***********************************************************************************/
28 #endregion
29
30 using System;
31 using System.Collections;
32 using System.ComponentModel;
33
34 namespace NUnit.Framework
35 {
36         /// <summary>
37         /// A set of Assert methods
38         /// </summary>
39         public class Assert
40         {
41                 private static int counter = 0;
42                 
43                 /// <summary>
44                 /// Gets the number of assertions executed so far and 
45                 /// resets the counter to zero.
46                 /// </summary>
47                 public static int Counter
48                 {
49                         get
50                         {
51                                 int cnt = counter;
52                                 counter = 0;
53                                 return cnt;
54                         }
55                 }
56
57                 /// <summary>
58                 /// A private constructor disallows any instances of this object. 
59                 /// </summary>
60                 private Assert()
61                 {}
62
63                 /// <summary>
64                 /// Asserts that a condition is true. If the condition is false the method throws
65                 /// an <see cref="AssertionException"/>.
66                 /// </summary> 
67                 /// <param name="message">The message to display if the condition is false</param>
68                 /// <param name="condition">The evaluated condition</param>
69                 static public void IsTrue(bool condition, string message) 
70                 {
71                         ++counter;
72                         if (!condition)
73                                 Assert.Fail(message);
74                 }
75     
76                 /// <summary>
77                 /// Asserts that a condition is true. If the condition is false the method throws
78                 /// an <see cref="AssertionException"/>.
79                 /// </summary>
80                 /// <param name="condition">The evaluated condition</param>
81                 static public void IsTrue(bool condition) 
82                 {
83                         Assert.IsTrue(condition, string.Empty);
84                 }
85
86                 /// <summary>
87                 /// Asserts that a condition is false. If the condition is true the method throws
88                 /// an <see cref="AssertionException"/>.
89                 /// </summary>
90                 /// <param name="message">The message to display if the condition is true</param>
91                 /// <param name="condition">The evaluated condition</param>
92                 static public void IsFalse(bool condition, string message) 
93                 {
94                         ++counter;
95                         if (condition)
96                                 Assert.Fail(message);
97                 }
98                 
99                 /// <summary>
100                 /// Asserts that a condition is false. If the condition is true the method throws
101                 /// an <see cref="AssertionException"/>.
102                 /// </summary>
103                 /// <param name="condition">The evaluated condition</param>
104                 static public void IsFalse(bool condition) 
105                 {
106                         Assert.IsFalse(condition, string.Empty);
107                 }
108
109                 /// <summary>
110                 /// Verifies that two doubles are equal considering a delta. If the
111                 /// expected value is infinity then the delta value is ignored. If 
112                 /// they are not equals then an <see cref="AssertionException"/> is
113                 /// thrown.
114                 /// </summary>
115                 /// <param name="message">The message that will be printed on failure</param>
116                 /// <param name="expected">The expected value</param>
117                 /// <param name="actual">The actual value</param>
118                 /// <param name="delta">The maximum acceptable difference between the
119                 /// the expected and the actual</param>
120                 static public void AreEqual(double expected, 
121                         double actual, double delta, string message) 
122                 {
123                         ++counter;
124                         // handle infinity specially since subtracting two infinite values gives 
125                         // NaN and the following test fails
126                         if (double.IsInfinity(expected)) 
127                         {
128                                 if (!(expected == actual))
129                                         Assert.FailNotEquals(expected, actual, message);
130                         } 
131                         else if (!(Math.Abs(expected-actual) <= delta))
132                                 Assert.FailNotEquals(expected, actual, message);
133                 }
134
135                 /// <summary>
136                 /// Verifies that two doubles are equal considering a delta. If the
137                 /// expected value is infinity then the delta value is ignored. If 
138                 /// they are not equals then an <see cref="AssertionException"/> is
139                 /// thrown.
140                 /// </summary>
141                 /// <param name="expected">The expected value</param>
142                 /// <param name="actual">The actual value</param>
143                 /// <param name="delta">The maximum acceptable difference between the
144                 /// the expected and the actual</param>
145                 static public void AreEqual(double expected, double actual, double delta) 
146                 {
147                         Assert.AreEqual(expected, actual, delta, string.Empty);
148                 }
149
150                 /// <summary>
151                 /// Verifies that two floats are equal considering a delta. If the
152                 /// expected value is infinity then the delta value is ignored. If 
153                 /// they are not equals then an <see cref="AssertionException"/> is
154                 /// thrown.
155                 /// </summary>
156                 /// <param name="message">The message printed out upon failure</param>
157                 /// <param name="expected">The expected value</param>
158                 /// <param name="actual">The actual value</param>
159                 /// <param name="delta">The maximum acceptable difference between the
160                 /// the expected and the actual</param>
161                 static public void AreEqual(float expected, 
162                         float actual, float delta, string message) 
163                 {
164                         ++counter;
165                         // handle infinity specially since subtracting two infinite values gives 
166                         // NaN and the following test fails
167                         if (float.IsInfinity(expected)) 
168                         {
169                                 if (!(expected == actual))
170                                         Assert.FailNotEquals(expected, actual, message);
171                         } 
172                         else if (!(Math.Abs(expected-actual) <= delta))
173                                 Assert.FailNotEquals(expected, actual, message);
174                 }
175
176                 /// <summary>
177                 /// Verifies that two floats are equal considering a delta. If the
178                 /// expected value is infinity then the delta value is ignored. If 
179                 /// they are not equals then an <see cref="AssertionException"/> is
180                 /// thrown.
181                 /// </summary>
182                 /// <param name="expected">The expected value</param>
183                 /// <param name="actual">The actual value</param>
184                 /// <param name="delta">The maximum acceptable difference between the
185                 /// the expected and the actual</param>
186                 static public void AreEqual(float expected, float actual, float delta) 
187                 {
188                         Assert.AreEqual(expected, actual, delta, string.Empty);
189                 }
190
191                 /// <summary>
192                 /// Verifies that two decimals are equal. If 
193                 /// they are not equals then an <see cref="AssertionException"/> is
194                 /// thrown.
195                 /// </summary>
196                 /// <param name="message">The message printed out upon failure</param>
197                 /// <param name="expected">The expected value</param>
198                 /// <param name="actual">The actual value</param>
199                 static public void AreEqual(decimal expected, decimal actual, string message) 
200                 {
201                         ++counter;
202                         if(!(expected == actual))
203                                 Assert.FailNotEquals(expected, actual, message);
204                 }
205
206                 /// <summary>
207                 /// Verifies that two decimals are equal. If 
208                 /// they are not equals then an <see cref="AssertionException"/> is
209                 /// thrown.
210                 /// </summary>
211                 /// <param name="expected">The expected value</param>
212                 /// <param name="actual">The actual value</param>
213                 static public void AreEqual(decimal expected, decimal actual) 
214                 {
215                         Assert.AreEqual(expected, actual, string.Empty);
216                 }
217                 
218                 /// <summary>
219                 /// Verifies that two ints are equal. If 
220                 /// they are not equals then an <see cref="AssertionException"/> is
221                 /// thrown.
222                 /// </summary>
223                 /// <param name="message">The message printed out upon failure</param>
224                 /// <param name="expected">The expected value</param>
225                 /// <param name="actual">The actual value</param>
226                 static public void AreEqual(int expected, int actual, string message) 
227                 {
228                         ++counter;
229                         if(!(expected == actual))
230                                 Assert.FailNotEquals(expected, actual, message);
231                 }
232
233                 /// <summary>
234                 /// Verifies that two ints are equal. If 
235                 /// they are not equals then an <see cref="AssertionException"/> is
236                 /// thrown.
237                 /// </summary>
238                 /// <param name="expected">The expected value</param>
239                 /// <param name="actual">The actual value</param>
240                 static public void AreEqual(int expected, int actual) 
241                 {
242                         Assert.AreEqual(expected, actual, string.Empty);
243                 }
244
245                 
246                 
247                 /// <summary>
248                 /// Verifies that two objects are equal.  Two objects are considered
249                 /// equal if both are null, or if both have the same value.  All
250                 /// non-numeric types are compared by using the <c>Equals</c> method.
251                 /// Arrays are compared by comparing each element using the same rules.
252                 /// If they are not equal an <see cref="AssertionException"/> is thrown.
253                 /// </summary>
254                 /// <param name="expected">The value that is expected</param>
255                 /// <param name="actual">The actual value</param>
256                 /// <param name="message">The message to display if objects are not equal</param>
257                 static public void AreEqual(Object expected, Object actual, string message)
258                 {
259                         ++counter;
260
261                         if (expected == null && actual == null) return;
262
263                         if (expected != null && actual != null)
264                         {
265                                 object[] aExpected = expected as object[];
266                                 object[] aActual = actual as object[];
267
268                                 if (aExpected != null && aActual != null )
269                                 {
270                                         int iLength = Math.Min( aExpected.Length, aActual.Length );
271                                         for( int i = 0; i < iLength; i++ )
272                                                 if ( !ObjectsEqual( aExpected[i], aActual[i] ) )
273                                                 {
274                                                         Assert.FailArraysNotEqual(i, aExpected, aActual, message );
275                                                 }
276
277                                         if ( aExpected.Length != aActual.Length )
278                                                 Assert.FailArraysNotEqual( iLength, aExpected, aActual, message );
279                                         
280                                         return;
281                                 }
282                                 else if(ObjectsEqual( expected, actual ))
283                                 {
284                                         return;
285                                 }
286                         }
287                         Assert.FailNotEquals(expected, actual, message);
288                 }
289
290                 /// <summary>
291                 /// Verifies that two objects are equal.  Two objects are considered
292                 /// equal if both are null, or if both have the same value.  All
293                 /// non-numeric types are compared by using the <c>Equals</c> method.
294                 /// If they are not equal an <see cref="AssertionException"/> is thrown.
295                 /// </summary>
296                 /// <param name="expected">The value that is expected</param>
297                 /// <param name="actual">The actual value</param>
298                 static public void AreEqual(Object expected, Object actual) 
299                 {
300                         Assert.AreEqual(expected, actual, string.Empty);
301                 }
302
303                 /// <summary>
304                 /// The Equals method throws an AssertionException. This is done 
305                 /// to make sure there is no mistake by calling this function.
306                 /// </summary>
307                 /// <param name="a"></param>
308                 /// <param name="b"></param>
309                 [EditorBrowsable(EditorBrowsableState.Never)]
310                 public static new bool Equals(object a, object b)
311                 {
312                         throw new AssertionException("Assert.Equals should not be used for Assertions");
313                 }
314
315                 /// <summary>
316                 /// override the default ReferenceEquals to throw an AssertionException. This 
317                 /// implementation makes sure there is no mistake in calling this function 
318                 /// as part of Assert. 
319                 /// </summary>
320                 /// <param name="a"></param>
321                 /// <param name="b"></param>
322                 public static new void ReferenceEquals(object a, object b)
323                 {
324                         throw new AssertionException("Assert.ReferenceEquals should not be used for Assertions");
325                 }
326                                 
327                 /// <summary>
328                 /// Checks the type of the object, returning true if
329                 /// the object is a numeric type.
330                 /// </summary>
331                 /// <param name="obj">The object to check</param>
332                 /// <returns>true if the object is a numeric type</returns>
333                 static private bool IsNumericType( Object obj )
334                 {
335                         if( null != obj )
336                         {
337                                 if( obj is byte    ) return true;
338                                 if( obj is sbyte   ) return true;
339                                 if( obj is decimal ) return true;
340                                 if( obj is double  ) return true;
341                                 if( obj is float   ) return true;
342                                 if( obj is int     ) return true;
343                                 if( obj is uint    ) return true;
344                                 if( obj is long    ) return true;
345                                 if( obj is short   ) return true;
346                                 if( obj is ushort  ) return true;
347
348                                 if( obj is System.Byte    ) return true;
349                                 if( obj is System.SByte   ) return true;
350                                 if( obj is System.Decimal ) return true;
351                                 if( obj is System.Double  ) return true;
352                                 if( obj is System.Single  ) return true;
353                                 if( obj is System.Int32   ) return true;
354                                 if( obj is System.UInt32  ) return true;
355                                 if( obj is System.Int64   ) return true;
356                                 if( obj is System.UInt64  ) return true;
357                                 if( obj is System.Int16   ) return true;
358                                 if( obj is System.UInt16  ) return true;
359                         }
360                         return false;
361                 }
362
363                 /// <summary>
364                 /// Used to compare numeric types.  Comparisons between
365                 /// same types are fine (Int32 to Int32, or Int64 to Int64),
366                 /// but the Equals method fails across different types.
367                 /// This method was added to allow any numeric type to
368                 /// be handled correctly, by using <c>ToString</c> and
369                 /// comparing the result
370                 /// </summary>
371                 /// <param name="expected"></param>
372                 /// <param name="actual"></param>
373                 /// <returns></returns>
374                 static private bool ObjectsEqual( Object expected, Object actual )
375                 {
376                         if( IsNumericType( expected )  &&
377                                 IsNumericType( actual ) )
378                         {
379                                 //
380                                 // Convert to strings and compare result to avoid
381                                 // issues with different types that have the same
382                                 // value
383                                 //
384                                 string sExpected = expected.ToString();
385                                 string sActual   = actual.ToString();
386                                 return sExpected.Equals( sActual );
387                         }
388                         return expected.Equals(actual);
389                 }
390     
391                 /// <summary>
392                 /// Verifies that the object that is passed in is not equal to <code>null</code>
393                 /// If the object is not <code>null</code> then an <see cref="AssertionException"/>
394                 /// is thrown.
395                 /// </summary>
396                 /// <param name="message">The message to be printed when the object is null</param>
397                 /// <param name="anObject">The object that is to be tested</param>
398                 static public void IsNotNull(Object anObject, string message) 
399                 {
400                         Assert.IsTrue(anObject != null, message); 
401                 }
402
403                 /// <summary>
404                 /// Verifies that the object that is passed in is not equal to <code>null</code>
405                 /// If the object is not <code>null</code> then an <see cref="AssertionException"/>
406                 /// is thrown.
407                 /// </summary>
408                 /// <param name="anObject">The object that is to be tested</param>
409                 static public void IsNotNull(Object anObject) 
410                 {
411                         Assert.IsNotNull(anObject, string.Empty);
412                 }
413     
414                     
415                 /// <summary>
416                 /// Verifies that the object that is passed in is equal to <code>null</code>
417                 /// If the object is <code>null</code> then an <see cref="AssertionException"/>
418                 /// is thrown.
419                 /// </summary>
420                 /// <param name="message">The message to be printed when the object is not null</param>
421                 /// <param name="anObject">The object that is to be tested</param>
422                 static public void IsNull(Object anObject, string message) 
423                 {
424                         Assert.IsTrue(anObject == null, message); 
425                 }
426
427                 /// <summary>
428                 /// Verifies that the object that is passed in is equal to <code>null</code>
429                 /// If the object is <code>null</code> then an <see cref="AssertionException"/>
430                 /// is thrown.
431                 /// </summary>
432                 /// <param name="anObject">The object that is to be tested</param>
433                 static public void IsNull(Object anObject) 
434                 {
435                         Assert.IsNull(anObject, string.Empty);
436                 }
437     
438     
439                 /// <summary>
440                 /// Asserts that two objects refer to the same object. If they
441                 /// are not the same an <see cref="AssertionException"/> is thrown.
442                 /// </summary>
443                 /// <param name="message">The message to be printed when the two objects are not the same object.</param>
444                 /// <param name="expected">The expected object</param>
445                 /// <param name="actual">The actual object</param>
446                 static public void AreSame(Object expected, Object actual, string message)
447                 {
448                         ++counter;
449                         if (object.ReferenceEquals(expected, actual)) return;
450
451                         Assert.FailNotSame(expected, actual, message);
452                 }
453
454                 /// <summary>
455                 /// Asserts that two objects refer to the same object. If they
456                 /// are not the same an <see cref="AssertionException"/> is thrown.
457                 /// </summary>
458                 /// <param name="expected">The expected object</param>
459                 /// <param name="actual">The actual object</param>
460                 static public void AreSame(Object expected, Object actual) 
461                 {
462                         Assert.AreSame(expected, actual, string.Empty);
463                 }
464    
465                 /// <summary>
466                 /// Throws an <see cref="AssertionException"/> with the message that is 
467                 /// passed in. This is used by the other Assert functions. 
468                 /// </summary>
469                 /// <param name="message">The message to initialize the <see cref="AssertionException"/> with.</param>
470                 static public void Fail(string message) 
471                 {
472                         if (message == null) message = string.Empty;
473
474                         throw new AssertionException(message);
475                 }
476
477                 /// <summary>
478                 /// Throws an <see cref="AssertionException"/> with the message that is 
479                 /// passed in. This is used by the other Assert functions. 
480                 /// </summary>
481                 static public void Fail() 
482                 {
483                         Assert.Fail(string.Empty);
484                 }
485     
486                 /// <summary>
487                 /// This method is called when two objects have been compared and found to be
488                 /// different. This prints a nice message to the screen. 
489                 /// </summary>
490                 /// <param name="message">The message that is to be printed prior to the comparison failure</param>
491                 /// <param name="expected">The expected object</param>
492                 /// <param name="actual">The actual object</param>
493                 static private void FailNotEquals(Object expected, Object actual, string message) 
494                 {
495                         Assert.Fail( 
496                                 AssertionFailureMessage.FormatMessageForFailNotEquals( 
497                                 expected, 
498                                 actual, 
499                                 message));
500                 }
501     
502                 /// <summary>
503                 /// This method is called when two arrays have been compared and found to be
504                 /// different. This prints a nice message to the screen. 
505                 /// </summary>
506                 /// <param name="message">The message that is to be printed prior to the comparison failure</param>
507                 /// <param name="expected">The expected array</param>
508                 /// <param name="actual">The actual array</param>
509                 static private void FailArraysNotEqual(int index, Object[] expected, Object[] actual, string message) 
510                 {
511                         Assert.Fail( 
512                                 AssertionFailureMessage.FormatMessageForFailArraysNotEqual( 
513                                 index,
514                                 expected, 
515                                 actual, 
516                                 message));
517                 }
518     
519                 /// <summary>
520                 ///  This method is called when the two objects are not the same. 
521                 /// </summary>
522                 /// <param name="message">The message to be printed on the screen</param>
523                 /// <param name="expected">The expected object</param>
524                 /// <param name="actual">The actual object</param>
525                 static private void FailNotSame(Object expected, Object actual, string message) 
526                 {
527                         string formatted=string.Empty;
528                         if (message != null)
529                                 formatted= message+" ";
530                         Assert.Fail(formatted+"expected same");
531                 }
532         }
533 }