1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.Collections.Generic;
\r
6 using System.ComponentModel.Composition;
\r
7 using System.ComponentModel.Composition.Hosting;
\r
9 using Microsoft.Internal;
\r
10 using Microsoft.VisualStudio.TestTools.UnitTesting;
\r
11 using System.UnitTesting;
\r
12 using Tests.Integration;
\r
13 using System.Reflection;
\r
14 using System.Reflection.Emit;
\r
16 namespace System.ComponentModel.Composition
\r
19 public class CompositionServicesTests
\r
21 private static readonly Type NonGenericType = typeof(int);
\r
24 public void GetContractName_NullAsTypeArgument_ThrowsArgumentNull()
\r
26 ExceptionAssert.ThrowsArgument<ArgumentNullException>("type", () =>
\r
28 AttributedModelServices.GetContractName((Type)null);
\r
33 [Description("Verifies adding custom modifiers to contract name.")]
\r
34 public void ContractNameServicesAddCustomModifiersTest()
\r
36 Type[] modifiers = new Type[] { typeof(int), typeof(List<int>), typeof(double) };
\r
37 StringBuilder typeName = new StringBuilder();
\r
38 ContractNameServices.WriteCustomModifiers(typeName, "test", modifiers);
\r
39 Assert.AreEqual<string>(
\r
40 string.Format(" {0}(System.Int32,System.Collections.Generic.List(System.Int32),System.Double)", "test"),
\r
41 typeName.ToString(),
\r
42 "Expecting correct modifiers text.");
\r
46 [Description("Verifies CompositionServices.GetDefaultContractName method.")]
\r
47 public void GetDefaultContractNameTest()
\r
49 ExpectationCollection<Type, string> expectations = new ExpectationCollection<Type, string>();
\r
51 expectations.Add(typeof(string), "System.String");
\r
52 expectations.Add(typeof(int?), "System.Nullable(System.Int32)");
\r
53 expectations.Add(typeof(NestedParent.NestedChild), "System.ComponentModel.Composition.NestedParent+NestedChild");
\r
54 expectations.Add(typeof(int[,]), "System.Int32[,]");
\r
55 expectations.Add(typeof(int[,][][]), "System.Int32[,][][]");
\r
56 expectations.Add(typeof(Array[,][][]).MakePointerType(), "System.Array[,][][]*");
\r
57 expectations.Add(typeof(int).MakePointerType(), "System.Int32*");
\r
58 expectations.Add(typeof(int).MakePointerType().MakeArrayType(3).MakeArrayType().MakePointerType(), "System.Int32*[][,,]*");
\r
59 expectations.Add(typeof(int).MakeByRefType(), "System.Int32&");
\r
60 expectations.Add(typeof(int).MakePointerType().MakeArrayType(4).MakeArrayType().MakeByRefType(), "System.Int32*[][,,,]&");
\r
61 expectations.Add(typeof(List<>), "System.Collections.Generic.List()");
\r
62 expectations.Add(typeof(Dictionary<int,double>), "System.Collections.Generic.Dictionary(System.Int32,System.Double)");
\r
63 expectations.Add(typeof(Dictionary<Dictionary<int,double>,double>), "System.Collections.Generic.Dictionary(System.Collections.Generic.Dictionary(System.Int32,System.Double),System.Double)");
\r
64 expectations.Add(typeof(GenericContract1<int>.GenericContract2.GenericContract3<double>), "System.ComponentModel.Composition.GenericContract1(System.Int32)+GenericContract2+GenericContract3(System.Double)");
\r
65 expectations.Add(typeof(GenericContract4<int,double>.GenericContract5<double,int>.GenericContract6<int,double>), "System.ComponentModel.Composition.GenericContract4(System.Int32,System.Double)+GenericContract5(System.Double,System.Int32)+GenericContract6(System.Int32,System.Double)");
\r
66 expectations.Add(typeof(GenericContract4<,>.GenericContract5<,>.GenericContract6<,>), "System.ComponentModel.Composition.GenericContract4(,)+GenericContract5(,)+GenericContract6(,)");
\r
67 expectations.Add(typeof(GenericContract7), "System.ComponentModel.Composition.GenericContract7");
\r
68 expectations.Add(typeof(GenericContract8<int>), "System.ComponentModel.Composition.GenericContract8(System.Int32)");
\r
69 expectations.Add(typeof(GenericContract4<int,double>.GenericContract5<double,int>[][,,,,]), "System.ComponentModel.Composition.GenericContract4(System.Int32,System.Double)+GenericContract5(System.Double,System.Int32)[][,,,,]");
\r
70 expectations.Add(typeof(GenericContract4<int,double>.GenericContract5<double,int>).MakePointerType(), "System.ComponentModel.Composition.GenericContract4(System.Int32,System.Double)+GenericContract5(System.Double,System.Int32)*");
\r
71 expectations.Add(typeof(GenericContract4<int,double>.GenericContract5<double,int>[][,]).MakePointerType().MakeArrayType(4), "System.ComponentModel.Composition.GenericContract4(System.Int32,System.Double)+GenericContract5(System.Double,System.Int32)[][,]*[,,,]"); expectations.Add(typeof(OuterClassWithGenericNested.GenericNested<int>), "System.ComponentModel.Composition.OuterClassWithGenericNested+GenericNested(System.Int32)");
\r
72 expectations.Add(typeof(Delegate), "System.Delegate");
\r
73 expectations.Add(typeof(MulticastDelegate), "System.MulticastDelegate");
\r
74 expectations.Add(typeof(Action), "System.Void()");
\r
75 expectations.Add(typeof(Func<Func<string>>), "System.Func(System.String)()");
\r
76 expectations.Add(typeof(DelegateCompositionTests.DoWorkDelegate), "System.Object(System.Int32,System.Object&,System.String&)");
\r
77 expectations.Add(typeof(DelegateCompositionTests.DelegateOneArg), "System.Int32(System.Int32)");
\r
78 expectations.Add(typeof(DelegateCompositionTests.DelegateTwoArgs), "System.Int32(System.Int32,System.Int32)");
\r
79 expectations.Add(typeof(DelegateCompositionTests.SimpleDelegate), "System.Int32()");
\r
80 expectations.Add(typeof(DelegateCompositionTests.ActionWith9Args), "System.Void(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)");
\r
81 expectations.Add(typeof(DelegateCompositionTests.FuncWith9Args), "System.Int32(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)");
\r
82 expectations.Add(EmitGenericType("MyGeneratedType", typeof(int)), "MyGeneratedType(System.Int32)");
\r
83 expectations.Add(EmitGenericType("MyGeneratedType`1", typeof(string)), "MyGeneratedType(System.String)");
\r
84 expectations.Add(EmitGenericType("_name_", typeof(List<>)), "_name_(System.Collections.Generic.List())");
\r
86 // This particular case can clash with the name generation for methods because we use () for both generics and methods
\r
87 // we may want to fix this clash by changing the generic markers but it is likely to be very rare.
\r
88 expectations.Add(EmitGenericType("System.Void", typeof(int)), "System.Void(System.Int32)");
\r
90 foreach (var e in expectations)
\r
92 string typeIdentity = AttributedModelServices.GetTypeIdentity(e.Input);
\r
93 Assert.AreEqual(e.Output, typeIdentity);
\r
96 // Do it again to excerise the cache.
\r
97 foreach (var e in expectations)
\r
99 string typeIdentity = AttributedModelServices.GetTypeIdentity(e.Input);
\r
100 Assert.AreEqual(e.Output, typeIdentity);
\r
104 public Type EmitGenericType(string typeName, Type genericArgumentType)
\r
106 var assemblyName = new AssemblyName("EmittedTestAssembly");
\r
107 var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
\r
108 var moduleBuilder = assemblyBuilder.DefineDynamicModule("EmittedTestModule");
\r
109 var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
\r
111 GenericTypeParameterBuilder T = typeBuilder.DefineGenericParameters(new string[] { "T" })[0];
\r
112 typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(ExportAttribute).GetConstructor(Type.EmptyTypes), new object[0]));
\r
114 return typeBuilder.CreateType().MakeGenericType(genericArgumentType);
\r