PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/redist/test/ComponentModelUnitTest/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinitionTests.cs

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