Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.ComponentModel.Composition / Tests / UnitTestFramework / System / UnitTesting / ExceptionAssert.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
6 using System.Runtime.Serialization;\r
7 \r
8 namespace System.UnitTesting\r
9 {\r
10     public static class ExceptionAssert\r
11     {\r
12         // NOTE: To catch state corrupting exceptions, it by design that \r
13         // the ThrowsXXX methods retry by default. To prevent this in a \r
14         // test, simply use one of the overloads that takes a RetryMode.\r
15 \r
16         /// <summary>\r
17         ///     Verifies that the exception has the default message generated by the base Exception class.\r
18         /// </summary>\r
19         public static void HasDefaultMessage(Exception exception)\r
20         {\r
21             Assert.IsNotNull(exception);\r
22 \r
23             // Exception of type '[typename]' was thrown\r
24             StringAssert.Contains(exception.Message, exception.GetType().FullName);\r
25         }\r
26 \r
27         /// <summary>\r
28         ///     Verifies that the specified action throws a SerializationException.\r
29         /// </summary>\r
30         public static SerializationException ThrowsSerialization(string memberName, Action action)\r
31         {\r
32             var exception = Throws<SerializationException>(RetryMode.Retry, action, (actual, retryCount) =>\r
33             {\r
34                 AssertSerializationMemberName(memberName, actual, retryCount);\r
35             });\r
36 \r
37             return exception;\r
38         }\r
39 \r
40         /// <summary>\r
41         ///     Verifies that the specified action throws an ObjectDisposedException.\r
42         /// </summary>\r
43         public static ObjectDisposedException ThrowsDisposed(object instance, Action action)            \r
44         {\r
45             var exception = Throws<ObjectDisposedException>(RetryMode.Retry, action, (actual, retryCount) =>\r
46             {\r
47                 AssertObjectDisposed(instance, actual, retryCount);\r
48             });\r
49 \r
50             return exception;\r
51         }\r
52 \r
53         /// <summary>\r
54         ///     Verifies that the specified action throws an ArgumentNullException.\r
55         /// </summary>\r
56         public static ArgumentNullException ThrowsArgumentNull(string parameterName, Action action)\r
57         {\r
58             return ThrowsArgument<ArgumentNullException>(parameterName, action);\r
59         }\r
60 \r
61         /// <summary>\r
62         ///     Verifies that the specified action throws an ArgumentException.\r
63         /// </summary>\r
64         public static ArgumentException ThrowsArgument(string parameterName, Action action)\r
65         {\r
66             return ThrowsArgument<ArgumentException>(parameterName, action);\r
67         }\r
68 \r
69         /// <summary>\r
70         ///     Verifies that the specified action throws an ArgumentException of type <typeparam name="T"/>.\r
71         /// </summary>\r
72         public static T ThrowsArgument<T>(string parameterName, Action action)\r
73             where T : ArgumentException\r
74         {\r
75             var exception = Throws<T>(RetryMode.Retry, action, (actual, retryCount) =>\r
76             {\r
77                 AssertSameParameterName(parameterName, actual, retryCount);\r
78             });\r
79 \r
80             return exception;\r
81         }\r
82 \r
83         /// <summary>\r
84         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
85         ///     with the specified inner exception of type <typeparam name="TInner"/>.\r
86         /// </summary>\r
87         public static T Throws<T, TInner>(Action action)\r
88             where T : Exception\r
89             where TInner : Exception\r
90         {\r
91             return Throws<T, TInner>(RetryMode.Retry, action);\r
92         }\r
93 \r
94         /// <summary>\r
95         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
96         ///     with the specified inner exception of type <typeparam name="TInner"/>, and indicating \r
97         ///     whether to retry.\r
98         /// </summary>\r
99         public static T Throws<T, TInner>(RetryMode retry, Action action)\r
100             where T : Exception\r
101             where TInner : Exception\r
102         {\r
103             return Throws<T, TInner>(retry, action, (Action<T, int>)null);\r
104         }\r
105 \r
106         /// <summary>\r
107         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
108         ///     with the specified inner exception of type <typeparam name="TInner"/>, indicating \r
109         ///     whether to retry and running the specified validator.\r
110         /// </summary>\r
111         public static T Throws<T, TInner>(RetryMode retry, Action action, Action<T, int> validator)\r
112             where T : Exception\r
113             where TInner : Exception\r
114         {\r
115             var exception = Throws<T>(retry, action, (actual, retryCount) =>\r
116             {\r
117                 AssertIsExactInstanceOfInner(typeof(TInner), actual, retryCount);\r
118 \r
119                 if (validator != null)\r
120                 {\r
121                     validator(actual, retryCount);\r
122                 }\r
123             });\r
124 \r
125             return exception;\r
126         }\r
127 \r
128         /// <summary>\r
129         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
130         ///     with the specified inner exception.\r
131         /// </summary>\r
132         public static T Throws<T>(Exception innerException, Action action)\r
133             where T : Exception\r
134         {\r
135             return Throws<T>(innerException, RetryMode.Retry, action, (Action<T, int>)null);\r
136         }\r
137 \r
138         /// <summary>\r
139         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
140         ///     with the specified inner exception, and indicating whether to retry.\r
141         /// </summary>\r
142         public static T Throws<T>(Exception innerException, RetryMode retry, Action action)\r
143             where T : Exception\r
144         {\r
145             return Throws<T>(innerException, RetryMode.Retry, action, (Action<T, int>)null);\r
146         }\r
147 \r
148         /// <summary>\r
149         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>,\r
150         ///     with the specified inner exception, indicating whether to retry and running the \r
151         ///     specified validator.\r
152         /// </summary>\r
153         public static T Throws<T>(Exception innerException, RetryMode retry, Action action, Action<T, int> validator)\r
154             where T : Exception\r
155         {\r
156             T exception = Throws<T>(retry, action, (actual, retryCount) =>\r
157             {\r
158                 AssertSameInner(innerException, actual, retryCount);\r
159 \r
160                 if (validator != null)\r
161                 {\r
162                     validator(actual, retryCount);\r
163                 }\r
164             });\r
165 \r
166             return exception;\r
167         }\r
168 \r
169         /// <summary>\r
170         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>.\r
171         /// </summary>\r
172         public static T Throws<T>(Action action)\r
173             where T : Exception\r
174         {\r
175             return Throws<T>(RetryMode.Retry, action, (Action<T, int>)null);\r
176         }\r
177 \r
178         /// <summary>\r
179         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>, \r
180         ///     indicating whether to retry.\r
181         /// </summary>\r
182         public static T Throws<T>(RetryMode retry, Action action)\r
183             where T : Exception\r
184         {\r
185             return Throws<T>(retry, action, (Action<T, int>)null);\r
186         }\r
187 \r
188         /// <summary>\r
189         ///     Verifies that the specified action throws an exception of type <typeparam name="T"/>, \r
190         ///     indicating whether to retry and running the specified validator.\r
191         /// </summary>\r
192         public static T Throws<T>(RetryMode retry, Action action, Action<T, int> validator)\r
193             where T : Exception\r
194         {\r
195             var exception = (T)Run(retry, action, (actual, retryCount) =>\r
196             {\r
197                 AssertIsExactInstanceOf(typeof(T), actual, retryCount);\r
198 \r
199                 if (validator != null)\r
200                 {\r
201                     validator((T)actual, retryCount);\r
202                 }\r
203             });\r
204 \r
205             return exception;\r
206         }\r
207 \r
208         /// <summary>\r
209         ///     Verifies that the specified action throws the specified exception.\r
210         /// </summary>\r
211         public static void Throws(Exception expected, Action action)\r
212         {\r
213             Throws(expected, RetryMode.Retry, action);\r
214         }\r
215 \r
216         /// <summary>\r
217         ///     Verifies that the specified action throws the specified exception,\r
218         ///     indicating whether to retry.\r
219         /// </summary>\r
220         public static void Throws(Exception expected, RetryMode retry, Action action)\r
221         {\r
222             Throws(expected, retry, action, (Action<Exception, int>)null);\r
223         }\r
224 \r
225         /// <summary>\r
226         ///     Verifies that the specified action throws the specified exception,\r
227         ///     indicating whether to retry and running the specified validator.\r
228         /// </summary>\r
229         public static void Throws(Exception expected, RetryMode retry, Action action, Action<Exception, int> validator)\r
230         {\r
231             Run(retry, action, (actual, retryCount) =>\r
232             {\r
233                 AssertSame(expected, actual, retryCount);\r
234 \r
235                 if (validator != null)\r
236                 {\r
237                     validator(actual, retryCount);\r
238                 }\r
239             });\r
240         }\r
241 \r
242         private static Exception Run(RetryMode retry, Action action, Action<Exception, int> validator)\r
243         {\r
244             Exception exception = null;\r
245 \r
246             for (int i = -1; i < (int)retry; i++)\r
247             {\r
248                 exception = Run(action);\r
249 \r
250                 validator(exception, i + 2);\r
251             }\r
252 \r
253             return exception;\r
254         }\r
255 \r
256         private static Exception Run(Action action)\r
257         {\r
258             try\r
259             {\r
260                 action();\r
261                 return null;\r
262             }\r
263             catch (Exception ex)\r
264             {\r
265                 return ex;\r
266             }\r
267         }\r
268 \r
269         private static void AssertSerializationMemberName(string memberName, SerializationException actual, int retryCount)\r
270         {\r
271             // Unfortunately, SerializationException does not provide a way to get our hands on the\r
272             // the actual member that was missing from the SerializationInfo, so we need to grok the \r
273             // message string.\r
274 \r
275             // Member '[memberName]' was not found.\r
276             StringAssert.Contains(actual.Message, "'" + memberName + "'", "Retry Count {0}: Expected SerializationException MemberName to be '{1}'", retryCount, memberName);\r
277         }\r
278 \r
279         private static void AssertObjectDisposed(object instance, ObjectDisposedException actual, int retryCount)\r
280         {\r
281             string objectName = instance.GetType().FullName;\r
282 \r
283             Assert.AreEqual(objectName, actual.ObjectName, "Retry Count {0}: Expected {1}.ObjectName to be '{2}', however, '{3}' is.", retryCount, actual.GetType().Name, objectName, actual.ObjectName);\r
284         }\r
285 \r
286         private static void AssertSameParameterName(string parameterName, ArgumentException actual, int retryCount)\r
287         {\r
288 #if !SILVERLIGHT    \r
289             Assert.AreEqual(parameterName, actual.ParamName, "Retry Count {0}: Expected {1}.ParamName to be '{2}', however, '{3}' is.", retryCount, actual.GetType().Name, parameterName, actual.ParamName);\r
290 #else\r
291             // Silverlight doesn't have ArgumentException.ParamName\r
292             StringAssert.Contains(actual.Message, parameterName, "Retry Count {0}: Expected {1}.ParamName to be '{2}'", retryCount, actual.GetType().Name, parameterName);\r
293 #endif\r
294         }\r
295 \r
296         private static void AssertSame(Exception expected, Exception actual, int retryCount)\r
297         {\r
298             Assert.AreSame(expected, actual, "Retry Count {0}: Expected '{1}' to be thrown, however, '{2}' was thrown.", retryCount, expected, actual);\r
299         }\r
300 \r
301         private static void AssertSameInner(Exception innerException, Exception actual, int retryCount)\r
302         {\r
303             Assert.AreSame(innerException, actual.InnerException, "Retry Count {0}: Expected '{1}' to be the inner exception, however, '{2}' is.", retryCount, innerException, actual.InnerException);\r
304         }\r
305 \r
306         private static void AssertIsExactInstanceOf(Type expectedType, Exception actual, int retryCount)\r
307         {\r
308             if (actual == null)\r
309                 Assert.Fail("Retry Count {0}: Expected '{1}' to be thrown", retryCount, expectedType);\r
310 \r
311             Type actualType = actual.GetType();\r
312 \r
313             Assert.AreSame(expectedType, actualType, "Retry Count {0}: Expected '{1}' to be thrown, however, '{2}' was thrown.", retryCount, expectedType, actualType);\r
314         }\r
315 \r
316         private static void AssertIsExactInstanceOfInner(Type expectedType, Exception actual, int retryCount)\r
317         {\r
318             if (actual.InnerException == null)\r
319                 Assert.Fail("Retry Count {0}: Expected '{1}' be the inner exception, however, it is null.", retryCount, expectedType);\r
320 \r
321             Type actualType = actual.InnerException.GetType();\r
322 \r
323             Assert.AreSame(expectedType, actualType, "Retry Count {0}: Expected '{1}' to be the inner exception, however, '{2}' is.", retryCount, expectedType, actualType);\r
324         }\r
325     }\r
326 }\r