[mcs] Validate more nameof argument expressions
[mono.git] / mcs / class / System.ComponentModel.Composition / Tests / ComponentModelUnitTest / System / ComponentModel / Composition / ReflectionModel / ReflectionComposablePartDefinitionTests.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.ComponentModel.Composition.Factories;\r
6 using System.ComponentModel.Composition.Hosting;\r
7 using System.ComponentModel.Composition.Primitives;\r
8 using System.Reflection;\r
9 using Microsoft.Internal;\r
10 using Microsoft.VisualStudio.TestTools.UnitTesting;\r
11 using System.Collections.Generic;\r
12 using System.Linq;\r
13 using System.UnitTesting;\r
14 using System.Threading;\r
15 \r
16 namespace System.ComponentModel.Composition.ReflectionModel\r
17 {\r
18     [TestClass]\r
19     public class ReflectionComposablePartDefinitionTests\r
20     {\r
21         private ReflectionComposablePartDefinition CreateReflectionPartDefinition(\r
22             Lazy<Type> partType,\r
23             bool requiresDisposal,\r
24             Func<IEnumerable<ImportDefinition>> imports,\r
25             Func<IEnumerable<ExportDefinition>>exports,\r
26             IDictionary<string, object> metadata,\r
27             ICompositionElement origin)\r
28         {\r
29             return (ReflectionComposablePartDefinition)ReflectionModelServices.CreatePartDefinition(partType, requiresDisposal, \r
30                 new Lazy<IEnumerable<ImportDefinition>>(imports, false), \r
31                 new Lazy<IEnumerable<ExportDefinition>>(exports, false), \r
32                 metadata.AsLazy(), origin);\r
33         }\r
34 \r
35         [TestMethod]\r
36         public void Constructor()\r
37         {\r
38             Type expectedType = typeof(TestPart);\r
39             Lazy<Type> expectedLazyType = expectedType.AsLazy();\r
40             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();\r
41             expectedMetadata["Key1"] = 1;\r
42             expectedMetadata["Key2"] = "Value2";\r
43 \r
44             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
45             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
46 \r
47             ICompositionElement expectedOrigin = new MockOrigin();\r
48 \r
49             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
50                 expectedLazyType,\r
51                 false,\r
52                 () => expectedImports,\r
53                 () => expectedExports,\r
54                 expectedMetadata,\r
55                 expectedOrigin);\r
56 \r
57             Assert.AreSame(expectedType, definition.GetPartType());\r
58             Assert.IsTrue(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));\r
59             Assert.IsTrue(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));\r
60             Assert.IsTrue(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));\r
61             Assert.IsTrue(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));\r
62             Assert.AreSame(expectedOrigin, ((ICompositionElement)definition).Origin);\r
63             Assert.IsNotNull(((ICompositionElement)definition).DisplayName);\r
64             Assert.IsFalse(definition.IsDisposalRequired);\r
65         }\r
66 \r
67         [TestMethod]\r
68         public void Constructor_DisposablePart()\r
69         {\r
70             Type expectedType = typeof(TestPart);\r
71             Lazy<Type> expectedLazyType = expectedType.AsLazy();\r
72             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();\r
73             expectedMetadata["Key1"] = 1;\r
74             expectedMetadata["Key2"] = "Value2";\r
75 \r
76             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
77             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
78 \r
79             ICompositionElement expectedOrigin = new MockOrigin();\r
80 \r
81             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
82                 expectedLazyType,\r
83                 true,\r
84                 () => expectedImports,\r
85                 () => expectedExports,\r
86                 expectedMetadata,\r
87                 expectedOrigin);\r
88 \r
89             Assert.AreSame(expectedType, definition.GetPartType());\r
90             Assert.IsTrue(definition.Metadata.Keys.SequenceEqual(expectedMetadata.Keys));\r
91             Assert.IsTrue(definition.Metadata.Values.SequenceEqual(expectedMetadata.Values));\r
92             Assert.IsTrue(definition.ExportDefinitions.SequenceEqual(expectedExports.Cast<ExportDefinition>()));\r
93             Assert.IsTrue(definition.ImportDefinitions.SequenceEqual(expectedImports.Cast<ImportDefinition>()));\r
94             Assert.AreSame(expectedOrigin, ((ICompositionElement)definition).Origin);\r
95             Assert.IsNotNull(((ICompositionElement)definition).DisplayName);\r
96             Assert.IsTrue(definition.IsDisposalRequired);\r
97         }\r
98 \r
99         [TestMethod]\r
100         public void CreatePart()\r
101         {\r
102             Type expectedType = typeof(TestPart);\r
103             Lazy<Type> expectedLazyType = expectedType.AsLazy();\r
104             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();\r
105             expectedMetadata["Key1"] = 1;\r
106             expectedMetadata["Key2"] = "Value2";\r
107 \r
108             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
109             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
110 \r
111             ICompositionElement expectedOrigin = new MockOrigin();\r
112 \r
113             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
114                 expectedLazyType,\r
115                 false,\r
116                 () => expectedImports,\r
117                 () => expectedExports,\r
118                 expectedMetadata,\r
119                 expectedOrigin);\r
120 \r
121             var part = definition.CreatePart();\r
122             Assert.IsNotNull(part);\r
123             Assert.IsFalse(part is IDisposable);\r
124         }\r
125 \r
126         [TestMethod]\r
127         public void CreatePart_Disposable()\r
128         {\r
129             Type expectedType = typeof(TestPart);\r
130             Lazy<Type> expectedLazyType = expectedType.AsLazy();\r
131             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();\r
132             expectedMetadata["Key1"] = 1;\r
133             expectedMetadata["Key2"] = "Value2";\r
134 \r
135             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
136             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
137 \r
138             ICompositionElement expectedOrigin = new MockOrigin();\r
139 \r
140             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
141                 expectedLazyType,\r
142                 true,\r
143                 () => expectedImports,\r
144                 () => expectedExports,\r
145                 expectedMetadata,\r
146                 expectedOrigin);\r
147 \r
148             var part = definition.CreatePart();\r
149             Assert.IsNotNull(part);\r
150             Assert.IsTrue(part is IDisposable);\r
151         }\r
152 \r
153         [TestMethod]\r
154         public void CreatePart_DoesntLoadType()\r
155         {\r
156             Type expectedType = typeof(TestPart);\r
157             Lazy<Type> expectedLazyType = new Lazy<Type>(() => { Assert.Fail("Part should not be loaded"); return null; });\r
158             IDictionary<string, object> expectedMetadata = new Dictionary<string, object>();\r
159             expectedMetadata["Key1"] = 1;\r
160             expectedMetadata["Key2"] = "Value2";\r
161 \r
162             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
163             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
164 \r
165             ICompositionElement expectedOrigin = new MockOrigin();\r
166 \r
167             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
168                 expectedLazyType,\r
169                 true,\r
170                 () => expectedImports,\r
171                 () => expectedExports,\r
172                 expectedMetadata,\r
173                 expectedOrigin);\r
174 \r
175             var part = definition.CreatePart();\r
176             Assert.IsNotNull(part);\r
177             Assert.IsTrue(part is IDisposable);\r
178         }\r
179 \r
180         [TestMethod]\r
181         public void Constructor_NullMetadata_ShouldSetMetadataPropertyToEmpty()\r
182         {\r
183             ReflectionComposablePartDefinition definition = CreateEmptyDefinition(typeof(object), typeof(object).GetConstructors().First(), null, new MockOrigin());\r
184             Assert.IsNotNull(definition.Metadata);\r
185             Assert.AreEqual(0, definition.Metadata.Count);\r
186         }\r
187 \r
188         [TestMethod]\r
189         public void Constructor_NullOrigin_ShouldSetOriginPropertyToNull()\r
190         {\r
191             ReflectionComposablePartDefinition definition = CreateEmptyDefinition(typeof(object), typeof(object).GetConstructors().First(), MetadataServices.EmptyMetadata, null);\r
192             Assert.IsNotNull(((ICompositionElement)definition).DisplayName);\r
193             Assert.IsNull(((ICompositionElement)definition).Origin);\r
194         }\r
195 \r
196         [TestMethod]\r
197         public void ImportaAndExports_CreatorsShouldBeCalledLazilyAndOnce()\r
198         {\r
199             Type expectedType = typeof(TestPart);\r
200 \r
201             IEnumerable<ImportDefinition> expectedImports = CreateImports(expectedType);\r
202             IEnumerable<ExportDefinition> expectedExports = CreateExports(expectedType);\r
203 \r
204             bool importsCreatorCalled = false;\r
205             Func<IEnumerable<ImportDefinition>> importsCreator = () =>\r
206             {\r
207                 Assert.IsFalse(importsCreatorCalled);\r
208                 importsCreatorCalled = true;\r
209                 return expectedImports.Cast<ImportDefinition>();\r
210             };\r
211 \r
212             bool exportsCreatorCalled = false;\r
213             Func<IEnumerable<ExportDefinition>> exportsCreator = () =>\r
214             {\r
215                 Assert.IsFalse(exportsCreatorCalled);\r
216                 exportsCreatorCalled = true;\r
217                 return expectedExports.Cast<ExportDefinition>();\r
218             };\r
219 \r
220             ReflectionComposablePartDefinition definition = CreateReflectionPartDefinition(\r
221                 expectedType.AsLazy(),\r
222                 false,\r
223                 importsCreator,\r
224                 exportsCreator,\r
225                 null,\r
226                 null);\r
227 \r
228             IEnumerable<ExportDefinition> exports;\r
229             Assert.IsFalse(exportsCreatorCalled);\r
230             exports = definition.ExportDefinitions;\r
231             Assert.IsTrue(exportsCreatorCalled);\r
232             exports = definition.ExportDefinitions;\r
233 \r
234 \r
235             IEnumerable<ImportDefinition> imports;\r
236             Assert.IsFalse(importsCreatorCalled);\r
237             imports = definition.ImportDefinitions;\r
238             Assert.IsTrue(importsCreatorCalled);\r
239             imports = definition.ImportDefinitions;\r
240         }\r
241 \r
242         [TestMethod]\r
243         public void ICompositionElementDisplayName_ShouldReturnTypeDisplayName()\r
244         {\r
245             var expectations = Expectations.GetAttributedTypes();\r
246             foreach (var e in expectations)\r
247             {\r
248                 var definition = (ICompositionElement)CreateEmptyDefinition(e, null, null, null);\r
249 \r
250                 Assert.AreEqual(e.GetDisplayName(), definition.DisplayName);\r
251             }\r
252         }\r
253 \r
254         [TestMethod]\r
255         public void ToString_ShouldReturnICompositionElementDisplayName()\r
256         {\r
257             var expectations = Expectations.GetAttributedTypes();\r
258             foreach (var e in expectations)\r
259             {\r
260                 var definition = (ICompositionElement)CreateEmptyDefinition(e, null, null, null);\r
261 \r
262                 Assert.AreEqual(definition.DisplayName, definition.ToString());\r
263             }\r
264         }\r
265 \r
266         private ReflectionComposablePartDefinition CreateEmptyDefinition(Type type, ConstructorInfo constructor, IDictionary<string, object> metadata, ICompositionElement origin)\r
267         {\r
268             return (ReflectionComposablePartDefinition)ReflectionModelServices.CreatePartDefinition(\r
269                 (type != null) ? type.AsLazy() : null,\r
270                 false,\r
271                 Enumerable.Empty<ImportDefinition>().AsLazy(),\r
272                 Enumerable.Empty<ExportDefinition>().AsLazy(),\r
273                 metadata.AsLazy(),\r
274                 origin);\r
275         }\r
276 \r
277         private static List<ImportDefinition> CreateImports(Type type)\r
278         {\r
279             List<ImportDefinition> imports = new List<ImportDefinition>();\r
280             foreach (PropertyInfo property in type.GetProperties())\r
281             {\r
282                 imports.Add(new ReflectionMemberImportDefinition(new LazyMemberInfo(property), "Contract", (string)null, new KeyValuePair<string, Type>[] { new KeyValuePair<string, Type>("Key1", typeof(object)) }, ImportCardinality.ZeroOrOne, true, CreationPolicy.Any, new TypeOrigin(type)));\r
283             }\r
284 \r
285             return imports;\r
286         }\r
287 \r
288         private static List<ExportDefinition> CreateExports(Type type)\r
289         {\r
290             List<ExportDefinition> exports = new List<ExportDefinition>();\r
291             foreach (PropertyInfo property in type.GetProperties())\r
292             {\r
293                 exports.Add(ReflectionModelServices.CreateExportDefinition(new LazyMemberInfo(property), "Contract", new Lazy<IDictionary<string, object>>(() => null, false), new TypeOrigin(type)));\r
294             }\r
295 \r
296             return exports;\r
297         }\r
298 \r
299         public class TestPart\r
300         {\r
301             public int field1;\r
302             public string field2;\r
303             public int Property1 { get; set; }\r
304             public string Property2 { get; set; }\r
305         }\r
306 \r
307         private class TypeOrigin : ICompositionElement\r
308         {\r
309             private readonly Type _type;\r
310             private readonly ICompositionElement _orgin; \r
311 \r
312             public TypeOrigin(Type type)\r
313                 : this(type, null)\r
314             {\r
315             }\r
316 \r
317             public TypeOrigin(Type type, ICompositionElement origin)\r
318             {\r
319                 this._type = type;\r
320                 this._orgin = origin;\r
321             }\r
322 \r
323             public string DisplayName\r
324             {\r
325                 get\r
326                 {\r
327                     return this._type.GetDisplayName();\r
328                 }\r
329             }\r
330 \r
331             public ICompositionElement Origin\r
332             {\r
333                 get\r
334                 {\r
335                     return this._orgin;\r
336                 }\r
337             }\r
338         }\r
339 \r
340         private class MockOrigin : ICompositionElement\r
341         {\r
342             public string DisplayName\r
343             {\r
344                 get { throw new NotImplementedException(); }\r
345             }\r
346 \r
347             public ICompositionElement Origin\r
348             {\r
349                 get { throw new NotImplementedException(); }\r
350             }\r
351         }\r
352     }\r
353 }\r