1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using System.Composition;
7 using System.Composition.Convention.UnitTests;
8 using System.Linq;
9 using System.Composition.Convention;
10 using System.Reflection;
11 using Xunit;
12 
13 namespace System.Composition.Convention
14 {
15     public class ExportBuilderTests
16     {
17         private interface IFoo { }
18 
19         private class FooImpl : IFoo { }
20 
21 
22         [Fact]
ExportInterfaceWithTypeOf1()23         public void ExportInterfaceWithTypeOf1()
24         {
25             var builder = new ConventionBuilder();
26             builder.ForType<FooImpl>().Export<IFoo>();
27 
28             var exports = builder.GetCustomAttributes(typeof(FooImpl), typeof(FooImpl).GetTypeInfo()).Where<Attribute>(e => e is ExportAttribute).Cast<ExportAttribute>();
29             Assert.Equal(1, exports.Count());
30             Assert.Equal(exports.First().ContractType, typeof(IFoo));
31         }
32 
33         [Fact]
ExportInterfaceWithTypeOf2()34         public void ExportInterfaceWithTypeOf2()
35         {
36             var builder = new ConventionBuilder();
37             builder.ForType(typeof(FooImpl)).Export((c) => c.AsContractType(typeof(IFoo)));
38 
39             var exports = builder.GetDeclaredAttributes(typeof(FooImpl), typeof(FooImpl).GetTypeInfo()).Where<Attribute>(e => e is ExportAttribute).Cast<ExportAttribute>();
40             Assert.Equal(1, exports.Count());
41             Assert.Equal(exports.First().ContractType, typeof(IFoo));
42         }
43 
44 
45         [Fact]
AsContractTypeOfT_SetsContractType()46         public void AsContractTypeOfT_SetsContractType()
47         {
48             var builder = new ConventionBuilder();
49             builder.ForTypesDerivedFrom<IFoo>().Export((e) => e.AsContractType<IFoo>());
50 
51             ExportAttribute exportAtt = GetExportAttribute(builder);
52             Assert.Equal(typeof(IFoo), exportAtt.ContractType);
53             Assert.Null(exportAtt.ContractName);
54         }
55 
56         [Fact]
AsContractType_SetsContractType()57         public void AsContractType_SetsContractType()
58         {
59             var builder = new ConventionBuilder();
60             builder.ForTypesDerivedFrom<IFoo>().Export((e) => e.AsContractType(typeof(IFoo)));
61 
62             ExportAttribute exportAtt = GetExportAttribute(builder);
63             Assert.Equal(typeof(IFoo), exportAtt.ContractType);
64             Assert.Null(exportAtt.ContractName);
65         }
66 
67         [Fact]
AsContractName_SetsContractName()68         public void AsContractName_SetsContractName()
69         {
70             var builder = new ConventionBuilder();
71             builder.ForTypesDerivedFrom<IFoo>().Export((e) => e.AsContractName("hey"));
72 
73             ExportAttribute exportAtt = GetExportAttribute(builder);
74             Assert.Equal("hey", exportAtt.ContractName);
75             Assert.Null(exportAtt.ContractType);
76         }
77 
78         [Fact]
AsContractName_AndContractType_SetsContractNameAndType()79         public void AsContractName_AndContractType_SetsContractNameAndType()
80         {
81             var builder = new ConventionBuilder();
82             builder.ForTypesDerivedFrom<IFoo>().Export((e) => e.AsContractName("hey").AsContractType(typeof(IFoo)));
83 
84             ExportAttribute exportAtt = GetExportAttribute(builder);
85             Assert.Equal("hey", exportAtt.ContractName);
86             Assert.Equal(typeof(IFoo), exportAtt.ContractType);
87         }
88 
89         [Fact]
AsContractName_AndContractType_ComputeContractNameFromType()90         public void AsContractName_AndContractType_ComputeContractNameFromType()
91         {
92             var builder = new ConventionBuilder();
93             builder.ForTypesDerivedFrom<IFoo>().Export(e => e.AsContractName(t => "Contract:" + t.FullName).AsContractType<IFoo>());
94 
95             ExportAttribute exportAtt = GetExportAttribute(builder);
96             Assert.Equal("Contract:" + typeof(FooImpl).FullName, exportAtt.ContractName);
97             Assert.Equal(typeof(IFoo), exportAtt.ContractType);
98         }
99 
100         [Fact]
AddMetadata_AddsExportMetadataAttribute()101         public void AddMetadata_AddsExportMetadataAttribute()
102         {
103             var builder = new ConventionBuilder();
104             builder.ForTypesDerivedFrom<IFoo>().Export(e => e.AddMetadata("name", "val"));
105 
106             ExportMetadataAttribute exportAtt = GetExportMetadataAttribute(builder);
107             Assert.Equal("name", exportAtt.Name);
108             Assert.Equal("val", exportAtt.Value);
109         }
110 
111         [Fact]
AddMetadataFuncVal_AddsExportMetadataAttribute()112         public void AddMetadataFuncVal_AddsExportMetadataAttribute()
113         {
114             var builder = new ConventionBuilder();
115             builder.ForTypesDerivedFrom<IFoo>().Export(e => e.AddMetadata("name", t => t.Name));
116 
117             ExportMetadataAttribute exportAtt = GetExportMetadataAttribute(builder);
118             Assert.Equal("name", exportAtt.Name);
119             Assert.Equal(typeof(FooImpl).Name, exportAtt.Value);
120         }
121 
GetExportAttribute(ConventionBuilder builder)122         private static ExportAttribute GetExportAttribute(ConventionBuilder builder)
123         {
124             var list = builder.GetDeclaredAttributes(typeof(FooImpl), typeof(FooImpl).GetTypeInfo());
125             Assert.Equal(1, list.Length);
126             return list[0] as ExportAttribute;
127         }
128 
GetExportMetadataAttribute(ConventionBuilder builder)129         private static ExportMetadataAttribute GetExportMetadataAttribute(ConventionBuilder builder)
130         {
131             var list = builder.GetDeclaredAttributes(typeof(FooImpl), typeof(FooImpl).GetTypeInfo());
132             Assert.Equal(2, list.Length);
133             return list[1] as ExportMetadataAttribute;
134         }
135     }
136 }
137