Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.ComponentModel.Composition / Tests / UnitTestFramework / System / ComponentModel / Composition / UnitTesting / CompositionAssert.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.ComponentModel.Composition;\r
6 using System.Linq;\r
7 using System.UnitTesting;\r
8 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
9 using System.Reflection;\r
10 using System.ComponentModel.Composition.Hosting;\r
11 using System.Collections.Generic;\r
12 using System.ComponentModel.Composition.Primitives;\r
13 \r
14 namespace System.ComponentModel.Composition.UnitTesting\r
15 {\r
16     public static class CompositionAssert\r
17     {\r
18         internal static void AreEqual(CompositionResult expected, CompositionResult actual)\r
19         {\r
20             Assert.AreEqual(expected.Succeeded, actual.Succeeded);\r
21 \r
22             EnumerableAssert.AreSequenceEqual(expected.Errors, actual.Errors, (index, expectedError, actualError) =>\r
23             {\r
24                 AreEqual(expectedError, actualError);\r
25             });\r
26         }\r
27 \r
28         internal static void AreEqual(CompositionError expected, CompositionError actual)\r
29         {\r
30             Assert.AreEqual(((ICompositionError)expected).Id, ((ICompositionError)actual).Id);\r
31             Assert.AreEqual(expected.Description, actual.Description);\r
32             ExtendedAssert.IsInstanceOfSameType(expected.Exception, actual.Exception);\r
33         }\r
34 \r
35         public static void ThrowsPart(ErrorId id, Action action)\r
36         {\r
37             ThrowsPart(id, RetryMode.Retry, action);\r
38         }\r
39 \r
40         public static void ThrowsPart(ErrorId id, RetryMode retry, Action action)\r
41         {\r
42             ThrowsPart(new CompositionErrorExpectation { Id = id }, retry, action);\r
43         }\r
44 \r
45         public static void ThrowsPart(ErrorId id, ICompositionElement element, Action action)\r
46         {\r
47             ThrowsPart(id, element, RetryMode.Retry, action);\r
48         }\r
49 \r
50         public static void ThrowsPart(ErrorId id, ICompositionElement element, RetryMode retry, Action action)\r
51         {\r
52             ThrowsPart(new CompositionErrorExpectation { Id = id, Element = element }, retry, action);\r
53         }\r
54 \r
55         public static void ThrowsPart<TInner>(ErrorId id, Action action)\r
56             where TInner : Exception\r
57         {\r
58             ThrowsPart<TInner>(id, RetryMode.Retry, action);\r
59         }\r
60 \r
61         public static void ThrowsPart<TInner>(ErrorId id, RetryMode retry, Action action)\r
62             where TInner : Exception\r
63         {\r
64             ThrowsPart(new CompositionErrorExpectation { Id = id, InnerExceptionType = typeof(TInner) }, retry, action);\r
65         }\r
66 \r
67         private static void ThrowsPart(CompositionErrorExpectation expectation, RetryMode retry, Action action)\r
68         {\r
69             ExceptionAssert.Throws<ComposablePartException>(retry, action, (thrownException, retryCount) =>\r
70             {\r
71                 AssertCore(retryCount, "ComposablePartException", thrownException, expectation);\r
72             });\r
73         }\r
74 \r
75         public static void ThrowsRootError(ErrorId rootId, RetryMode retry, Action action)\r
76         {\r
77             var exception = ExceptionAssert.Throws<CompositionException>(retry, action, (thrownException, retryCount) =>\r
78             {\r
79                 ErrorId actualId = GetRootErrorId(thrownException);\r
80 \r
81                 Assert.AreEqual(rootId, actualId, "Retry Count {0}: Expected '{1}' to be the root ErrorId, however, '{2}' is.", retryCount, rootId, actualId);\r
82             });\r
83         }\r
84 \r
85         public static void ThrowsError<TInner>(ErrorId id, RetryMode retry, Action action)\r
86         {\r
87             ThrowsError(new CompositionErrorExpectation { Id = id, InnerExceptionType = typeof(TInner) }, RetryMode.Retry, action);\r
88         }\r
89 \r
90         public static void ThrowsError(ErrorId id, Action action)\r
91         {\r
92             ThrowsError(new CompositionErrorExpectation { Id = id}, RetryMode.Retry, action);\r
93         }\r
94 \r
95         public static void ThrowsError(ErrorId id, ErrorId innerId, Action action)\r
96         {\r
97             ThrowsError(id, innerId, RetryMode.Retry, action);\r
98         }\r
99 \r
100         public static void ThrowsError(ErrorId id, ErrorId innerId, RetryMode retry, Action action)\r
101         {\r
102             ThrowsError(GetExpectation(id, innerId), retry, action);\r
103         }\r
104 \r
105         public static void ThrowsError(ErrorId id, ErrorId innerId, ErrorId innerInnerId, Action action)\r
106         {\r
107             ThrowsError(id, innerId, innerInnerId, RetryMode.Retry, action);\r
108         }\r
109 \r
110         public static void ThrowsError(ErrorId id, ErrorId innerId, ErrorId innerInnerId, RetryMode retry, Action action)\r
111         {\r
112             ThrowsError(GetExpectation(id, innerId, innerInnerId), retry, action);\r
113         }\r
114 \r
115         public static void ThrowsError(ErrorId id, RetryMode retry, Action action)\r
116         {\r
117             ThrowsError(new CompositionErrorExpectation { Id = id, }, retry, action);\r
118         }\r
119 \r
120         public static void ThrowsError(ErrorId id, ICompositionElement element, Action action)\r
121         {\r
122             ThrowsError(new CompositionErrorExpectation { Id = id, Element = element}, RetryMode.Retry, action);\r
123         }\r
124 \r
125         public static void ThrowsError(ErrorId id, ICompositionElement element, RetryMode retry, Action action)\r
126         {\r
127             ThrowsError(new CompositionErrorExpectation { Id = id, Element = element }, retry, action);\r
128         }\r
129 \r
130         public static void ThrowsError(ErrorId id, Exception exception, Action action)\r
131         {\r
132             ThrowsError(new CompositionErrorExpectation { Id = id, InnerException = exception }, RetryMode.Retry, action);\r
133         }\r
134 \r
135         public static void ThrowsError(ErrorId id, Exception exception, RetryMode retry, Action action)\r
136         {\r
137             ThrowsError(new CompositionErrorExpectation { Id = id, InnerException = exception }, retry, action);\r
138         }\r
139 \r
140         public static void ThrowsError(ErrorId id, ICompositionElement element, Exception exception, Action action)\r
141         {\r
142             ThrowsError(new CompositionErrorExpectation { Id = id, Element = element, InnerException = exception }, RetryMode.Retry, action);\r
143         }\r
144 \r
145         public static void ThrowsError(ErrorId id, ICompositionElement element, Exception exception, RetryMode retry, Action action)\r
146         {\r
147             ThrowsError(new CompositionErrorExpectation { Id = id, Element = element, InnerException = exception }, retry, action);\r
148         }\r
149 \r
150         private static void ThrowsError(CompositionErrorExpectation expectation, RetryMode retry, Action action)\r
151         {\r
152             ThrowsErrors(new CompositionErrorExpectation[] { expectation }, retry, action);\r
153         }\r
154 \r
155         public static void ThrowsErrors(ErrorId id1, ErrorId id2, Action action)\r
156         {\r
157             ThrowsErrors(id1, id2, RetryMode.Retry, action);\r
158         }\r
159 \r
160         public static void ThrowsErrors(ErrorId id1, ErrorId id2, RetryMode retry, Action action)\r
161         {\r
162             ThrowsErrors(new ErrorId[] { id1, id2 }, retry, action);\r
163         }\r
164 \r
165         public static void ThrowsErrors(ErrorId[] ids, RetryMode retry, Action action)\r
166         {\r
167             CompositionErrorExpectation[] expectations = new CompositionErrorExpectation[ids.Length]; \r
168             for (int i = 0; i < expectations.Length; i++)\r
169             {\r
170                 expectations[i] = new CompositionErrorExpectation { Id = ids[i] };\r
171             }\r
172 \r
173             ThrowsErrors(expectations, retry, action);\r
174         }\r
175 \r
176         private static void ThrowsErrors(CompositionErrorExpectation[] expectations, RetryMode retry, Action action)\r
177         {\r
178             ExceptionAssert.Throws<CompositionException>(retry, action, (thrownException, retryCount) =>\r
179             {\r
180                 AssertCore(retryCount, "CompositionException", thrownException, expectations);\r
181             });\r
182         }\r
183 \r
184         public static void ThrowsChangeRejectedRootError(ErrorId rootId, RetryMode retry, Action action)\r
185         {\r
186             var exception = ExceptionAssert.Throws<ChangeRejectedException>(retry, action, (thrownException, retryCount) =>\r
187             {\r
188                 ErrorId actualId = GetRootErrorId(thrownException);\r
189 \r
190                 Assert.AreEqual(rootId, actualId, "Retry Count {0}: Expected '{1}' to be the root ErrorId, however, '{2}' is.", retryCount, rootId, actualId);\r
191             });\r
192         }\r
193 \r
194         public static void ThrowsChangeRejectedError(ErrorId id, Action action)\r
195         {\r
196             ThrowsChangeRejectedError(new CompositionErrorExpectation { Id = id }, RetryMode.Retry, action);\r
197         }\r
198 \r
199         public static void ThrowsChangeRejectedError(ErrorId id, RetryMode retry, Action action)\r
200         {\r
201             ThrowsChangeRejectedError(new CompositionErrorExpectation { Id = id, }, retry, action);\r
202         }\r
203 \r
204         public static void ThrowsChangeRejectedError(ErrorId id, ICompositionElement element, Action action)\r
205         {\r
206             ThrowsChangeRejectedError(new CompositionErrorExpectation { Id = id, Element = element }, RetryMode.Retry, action);\r
207         }\r
208 \r
209         public static void ThrowsChangeRejectedError(ErrorId id, ErrorId innerId, RetryMode retry, Action action)\r
210         {\r
211             ThrowsChangeRejectedError(GetExpectation(id, innerId), retry, action);\r
212         }\r
213 \r
214         public static void ThrowsChangeRejectedError(ErrorId id, ErrorId innerId, ErrorId innerInnerId, Action action)\r
215         {\r
216             ThrowsChangeRejectedError(id, innerId, innerInnerId, RetryMode.Retry, action);\r
217         }\r
218 \r
219         public static void ThrowsChangeRejectedError(ErrorId id, ErrorId innerId, ErrorId innerInnerId, RetryMode retry, Action action)\r
220         {\r
221             ThrowsChangeRejectedError(GetExpectation(id, innerId, innerInnerId), retry, action);\r
222         }\r
223 \r
224         private static void ThrowsChangeRejectedError(CompositionErrorExpectation expectation, RetryMode retry, Action action)\r
225         {\r
226             ThrowsChangeRejectedErrors(new CompositionErrorExpectation[] { expectation }, retry, action);\r
227         }\r
228 \r
229         public static void ThrowsChangeRejectedError(ErrorId id, ICompositionElement element, Exception exception, Action action)\r
230         {\r
231             ThrowsChangeRejectedError(new CompositionErrorExpectation { Id = id, Element = element, InnerException = exception }, RetryMode.Retry, action);\r
232         }\r
233 \r
234         public static void ThrowsChangeRejectedErrors(ErrorId id1, ErrorId id2, RetryMode retry, Action action)\r
235         {\r
236             ThrowsChangeRejectedErrors(new ErrorId[] { id1, id2 }, retry, action);\r
237         }\r
238 \r
239         public static void ThrowsChangeRejectedErrors(ErrorId[] ids, RetryMode retry, Action action)\r
240         {\r
241             CompositionErrorExpectation[] expectations = new CompositionErrorExpectation[ids.Length];\r
242             for (int i = 0; i < expectations.Length; i++)\r
243             {\r
244                 expectations[i] = new CompositionErrorExpectation { Id = ids[i] };\r
245             }\r
246 \r
247             ThrowsChangeRejectedErrors(expectations, retry, action);\r
248         }\r
249 \r
250         private static void ThrowsChangeRejectedErrors(CompositionErrorExpectation[] expectations, RetryMode retry, Action action)\r
251         {\r
252             ExceptionAssert.Throws<ChangeRejectedException>(retry, action, (thrownException, retryCount) =>\r
253             {\r
254                 AssertCore(retryCount, "CompositionException", thrownException, expectations);\r
255             });\r
256         }\r
257 \r
258         private static void AssertCore(int retryCount, string prefix, CompositionException exception, CompositionErrorExpectation[] expectations)\r
259         {\r
260             Assert.AreEqual(exception.Errors.Count, expectations.Length);\r
261 \r
262             for (int i = 0; i < exception.Errors.Count; i++)\r
263             {\r
264                 AssertCore(retryCount, prefix + ".Errors[" + i + "]", exception.Errors[i], expectations[i]);\r
265             }\r
266         }\r
267 \r
268         private static void AssertCore(int retryCount, string prefix, ICompositionError error, CompositionErrorExpectation expectation)\r
269         {\r
270             if (expectation.IdSpecified)\r
271             {\r
272                 AssertCore(retryCount, prefix, "Id", expectation.Id, (ErrorId)error.Id);\r
273             }\r
274 \r
275             if (expectation.ElementSpecified)\r
276             {\r
277                 AssertCore(retryCount, prefix, "Element", expectation.Element, error.Element);\r
278             }\r
279 \r
280             if (expectation.InnerExceptionSpecified)\r
281             {\r
282                 AssertCore(retryCount, prefix, "InnerException", expectation.InnerException, error.InnerException);\r
283             }\r
284 \r
285             if (expectation.InnerExceptionTypeSpecified)\r
286             {\r
287                 AssertCore(retryCount, prefix, "InnerException.GetType()", expectation.InnerExceptionType, error.InnerException == null ? null : error.InnerException.GetType());\r
288             }\r
289 \r
290             if (expectation.InnerExpectationsSpecified)\r
291             {\r
292                 ICompositionError innerError = error.InnerException as ICompositionError;\r
293                 if (innerError != null)\r
294                 {\r
295                     Assert.AreEqual(1, expectation.InnerExpectations.Length);\r
296                     AssertCore(retryCount, prefix + ".InnerException", innerError, expectation.InnerExpectations[0]);\r
297                 }\r
298                 else\r
299                 {\r
300                     AssertCore(retryCount, prefix + ".InnerException", (CompositionException)error.InnerException, expectation.InnerExpectations);\r
301                 }\r
302             }\r
303         }\r
304                \r
305         private static void AssertCore<T>(int retryCount, string prefix, string propertyName, T expected, T actual)\r
306         {\r
307             Assert.AreEqual(expected, actual, "Retry Count {0}: Expected '{1}' to be {3}.{4}, however, '{2}' is.", retryCount, expected, actual, prefix, propertyName);\r
308         }\r
309 \r
310         private static CompositionErrorExpectation GetExpectation(params ErrorId[] ids)\r
311         {\r
312             var parent = new CompositionErrorExpectation() { Id = ids[0] };\r
313             var expectation = parent;\r
314 \r
315             for (int i = 1; i < ids.Length; i++)\r
316             {\r
317                 expectation.InnerExpectations = new CompositionErrorExpectation[] { new CompositionErrorExpectation() { Id = ids[i] } };\r
318                 expectation = expectation.InnerExpectations[0];\r
319             }\r
320 \r
321             return parent;\r
322         }\r
323 \r
324         private static ErrorId GetRootErrorId(CompositionException exception)\r
325         {\r
326             Assert.IsTrue(exception.Errors.Count == 1);\r
327 \r
328             return GetRootErrorId(exception.Errors[0]);\r
329         }\r
330 \r
331         private static ErrorId GetRootErrorId(ICompositionError error)\r
332         {\r
333             Exception exception = error.InnerException;\r
334 \r
335             var childError = exception as ICompositionError;\r
336             if (childError != null)\r
337             {\r
338                 return GetRootErrorId(childError);\r
339             }\r
340 \r
341             CompositionException composition = exception as CompositionException;\r
342             if (composition != null)\r
343             {\r
344                 return GetRootErrorId(composition);\r
345             }\r
346 \r
347             return (ErrorId)error.Id;\r
348         }\r
349 \r
350         private class CompositionErrorExpectation\r
351         {\r
352             private ErrorId _id;\r
353             private Exception _innerException;\r
354             private Type _innerExceptionType;\r
355             private ICompositionElement _element;\r
356             private CompositionErrorExpectation[] _innerExpectations;\r
357 \r
358             public ErrorId Id\r
359             {\r
360                 get { return _id; }\r
361                 set\r
362                 {\r
363                     _id = value;\r
364                     IdSpecified = true;\r
365                 }\r
366             }\r
367 \r
368             public Exception InnerException\r
369             {\r
370                 get { return _innerException; }\r
371                 set\r
372                 {\r
373                     _innerException = value;\r
374                     InnerExceptionSpecified = true;\r
375                 }\r
376             }\r
377 \r
378             public Type InnerExceptionType\r
379             {\r
380                 get { return _innerExceptionType; }\r
381                 set\r
382                 {\r
383                     _innerExceptionType = value;\r
384                     InnerExceptionTypeSpecified = true;\r
385                 }\r
386             }\r
387 \r
388             public ICompositionElement Element\r
389             {\r
390                 get { return _element; }\r
391                 set\r
392                 {\r
393                     _element = value;\r
394                     ElementSpecified = true;\r
395                 }\r
396             }\r
397 \r
398             public CompositionErrorExpectation[] InnerExpectations\r
399             {\r
400                 get { return _innerExpectations; }\r
401                 set\r
402                 {\r
403                     _innerExpectations = value;\r
404                     InnerExpectationsSpecified = true;\r
405                 }\r
406             }\r
407 \r
408             public bool IdSpecified\r
409             {\r
410                 get;\r
411                 private set;\r
412             }\r
413 \r
414             public bool InnerExceptionSpecified\r
415             {\r
416                 get;\r
417                 private set;\r
418             }\r
419 \r
420             public bool InnerExceptionTypeSpecified\r
421             {\r
422                 get;\r
423                 private set;\r
424             }\r
425 \r
426             public bool ElementSpecified\r
427             {\r
428                 get;\r
429                 private set;\r
430             }\r
431 \r
432             public bool InnerExpectationsSpecified\r
433             {\r
434                 get;\r
435                 private set;\r
436             }\r
437         }\r
438     }\r
439 }\r