Skip to content

Commit 9d4fa52

Browse files
committed
Add verification tests for the source generator.
1 parent 63b979b commit 9d4fa52

28 files changed

Lines changed: 1074 additions & 3 deletions

File tree

Autofac.Extras.AggregateService.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autofac.Extras.AggregateSer
3939
EndProject
4040
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autofac.Extras.AggregateService.SourceGenerator", "src\Autofac.Extras.AggregateService.SourceGenerator\Autofac.Extras.AggregateService.SourceGenerator.csproj", "{A92990BE-D76A-4130-B281-9163CDE2A2B3}"
4141
EndProject
42+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Autofac.Extras.AggregateService.SourceGenerator.Test", "test\Autofac.Extras.AggregateService.SourceGenerator.Test\Autofac.Extras.AggregateService.SourceGenerator.Test.csproj", "{94A5473A-8466-4E2E-BB6F-A665EE127B89}"
43+
EndProject
4244
Global
4345
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4446
Debug|Any CPU = Debug|Any CPU
@@ -97,6 +99,18 @@ Global
9799
{A92990BE-D76A-4130-B281-9163CDE2A2B3}.Release|x64.Build.0 = Release|Any CPU
98100
{A92990BE-D76A-4130-B281-9163CDE2A2B3}.Release|x86.ActiveCfg = Release|Any CPU
99101
{A92990BE-D76A-4130-B281-9163CDE2A2B3}.Release|x86.Build.0 = Release|Any CPU
102+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
103+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|Any CPU.Build.0 = Debug|Any CPU
104+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|x64.ActiveCfg = Debug|Any CPU
105+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|x64.Build.0 = Debug|Any CPU
106+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|x86.ActiveCfg = Debug|Any CPU
107+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Debug|x86.Build.0 = Debug|Any CPU
108+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|Any CPU.ActiveCfg = Release|Any CPU
109+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|Any CPU.Build.0 = Release|Any CPU
110+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|x64.ActiveCfg = Release|Any CPU
111+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|x64.Build.0 = Release|Any CPU
112+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|x86.ActiveCfg = Release|Any CPU
113+
{94A5473A-8466-4E2E-BB6F-A665EE127B89}.Release|x86.Build.0 = Release|Any CPU
100114
EndGlobalSection
101115
GlobalSection(SolutionProperties) = preSolution
102116
HideSolutionNode = FALSE
@@ -106,6 +120,7 @@ Global
106120
{48B716B8-716E-4D71-8BD3-0BB4B6E35726} = {ADBDED51-3557-4AC9-BCDA-144D6834FDE5}
107121
{FD927CB2-53BE-453A-B135-7E7680F9DF16} = {760AB15A-8938-8D9B-BEDE-5CE1484B84C3}
108122
{A92990BE-D76A-4130-B281-9163CDE2A2B3} = {0D0EADE5-8158-4FBC-833C-3B6CF07C7C08}
123+
{94A5473A-8466-4E2E-BB6F-A665EE127B89} = {ADBDED51-3557-4AC9-BCDA-144D6834FDE5}
109124
EndGlobalSection
110125
GlobalSection(ExtensibilityGlobals) = postSolution
111126
SolutionGuid = {E39D3F0A-B882-49B8-ABFF-BA8BEAB81863}

src/Autofac.Extras.AggregateService.SourceGenerator/Autofac.Extras.AggregateService.SourceGenerator.csproj

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
<SignAssembly>true</SignAssembly>
1313
<NeutralLanguage>en-US</NeutralLanguage>
1414
<!-- Frameworks and language features -->
15-
<!-- Source generators must target netstandard2.0 - that is the framework the Roslyn
16-
compiler host loads analyzers as. -->
15+
<!--
16+
Source generators must target netstandard2.0 - that is the framework the
17+
Roslyn compiler host loads analyzers as.
18+
-->
1719
<TargetFramework>netstandard2.0</TargetFramework>
1820
<LangVersion>latest</LangVersion>
1921
<Nullable>enable</Nullable>
@@ -51,6 +53,9 @@
5153
order to run the generator. Consumers on older compilers simply do not run
5254
it and fall back to the Castle DynamicProxy path, so a newer version
5355
degrades safely rather than breaking.
56+
57+
If you change the Microsoft.CodeAnalysis.CSharp version, update the test
58+
project reference to match.
5459
-->
5560
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="[4.14.0]">
5661
<PrivateAssets>all</PrivateAssets>
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
// Copyright (c) Autofac Project. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
namespace Autofac.Extras.AggregateService.SourceGenerator.Test;
5+
6+
public class AggregateServiceSourceGeneratorTests
7+
{
8+
[Fact]
9+
public Task RegisterAggregateService_GenericForm()
10+
{
11+
var source = Wrap(@"
12+
public interface IMyService { }
13+
14+
public interface IMyAggregate
15+
{
16+
IMyService MyService { get; }
17+
}
18+
19+
public static class Registration
20+
{
21+
public static void Configure(ContainerBuilder builder)
22+
{
23+
builder.RegisterAggregateService<IMyAggregate>();
24+
}
25+
}");
26+
27+
return Verify(GeneratorTestHarness.Run(source));
28+
}
29+
30+
[Fact]
31+
public Task RegisterAggregateService_TypeofForm()
32+
{
33+
var source = Wrap(@"
34+
public interface IMyService { }
35+
36+
public interface IMyAggregate
37+
{
38+
IMyService MyService { get; }
39+
}
40+
41+
public static class Registration
42+
{
43+
public static void Configure(ContainerBuilder builder)
44+
{
45+
builder.RegisterAggregateService(typeof(IMyAggregate));
46+
}
47+
}");
48+
49+
return Verify(GeneratorTestHarness.Run(source));
50+
}
51+
52+
[Fact]
53+
public Task CreateInstance_GenericForm()
54+
{
55+
var source = Wrap(@"
56+
public interface IMyService { }
57+
58+
public interface IMyAggregate
59+
{
60+
IMyService MyService { get; }
61+
}
62+
63+
public static class Registration
64+
{
65+
public static object Configure(IComponentContext context)
66+
{
67+
return AggregateServiceGenerator.CreateInstance<IMyAggregate>(context);
68+
}
69+
}");
70+
71+
return Verify(GeneratorTestHarness.Run(source));
72+
}
73+
74+
[Fact]
75+
public Task CreateInstance_TypeofForm()
76+
{
77+
var source = Wrap(@"
78+
public interface IMyService { }
79+
80+
public interface IMyAggregate
81+
{
82+
IMyService MyService { get; }
83+
}
84+
85+
public static class Registration
86+
{
87+
public static object Configure(IComponentContext context)
88+
{
89+
return AggregateServiceGenerator.CreateInstance(typeof(IMyAggregate), context);
90+
}
91+
}");
92+
93+
return Verify(GeneratorTestHarness.Run(source));
94+
}
95+
96+
[Fact]
97+
public Task Properties_ResolvedEagerly_SetterThrows()
98+
{
99+
var source = Wrap(@"
100+
public interface IMyService { }
101+
102+
public interface IMyAggregate
103+
{
104+
IMyService ReadOnly { get; }
105+
IMyService WithSetter { get; set; }
106+
}
107+
108+
public static class Registration
109+
{
110+
public static void Configure(ContainerBuilder builder)
111+
{
112+
builder.RegisterAggregateService<IMyAggregate>();
113+
}
114+
}");
115+
116+
return Verify(GeneratorTestHarness.Run(source));
117+
}
118+
119+
[Fact]
120+
public Task Methods_AllShapes()
121+
{
122+
var source = Wrap(@"
123+
public interface IMyService { }
124+
125+
public interface IMyAggregate
126+
{
127+
IMyService GetService();
128+
IMyService GetService(int value);
129+
IMyService GetService(System.DateTime date, string name);
130+
void DoNothing();
131+
}
132+
133+
public static class Registration
134+
{
135+
public static void Configure(ContainerBuilder builder)
136+
{
137+
builder.RegisterAggregateService<IMyAggregate>();
138+
}
139+
}");
140+
141+
return Verify(GeneratorTestHarness.Run(source));
142+
}
143+
144+
[Fact]
145+
public Task GenericMethods()
146+
{
147+
var source = Wrap(@"
148+
public interface IThing<T> { }
149+
150+
public interface IMyAggregate
151+
{
152+
IThing<T> Get<T>();
153+
IThing<T> Use<T>(IThing<T> existing);
154+
}
155+
156+
public static class Registration
157+
{
158+
public static void Configure(ContainerBuilder builder)
159+
{
160+
builder.RegisterAggregateService<IMyAggregate>();
161+
}
162+
}");
163+
164+
return Verify(GeneratorTestHarness.Run(source));
165+
}
166+
167+
[Fact]
168+
public Task OpenGenericInterface()
169+
{
170+
var source = Wrap(@"
171+
public interface IThing<T> { }
172+
173+
public interface IMyAggregate<T>
174+
{
175+
T Item { get; }
176+
IThing<T> Thing { get; }
177+
}
178+
179+
public static class Registration
180+
{
181+
public static void Configure(ContainerBuilder builder)
182+
{
183+
builder.RegisterAggregateService(typeof(IMyAggregate<>));
184+
}
185+
}");
186+
187+
return Verify(GeneratorTestHarness.Run(source));
188+
}
189+
190+
[Fact]
191+
public Task InheritedInterfaceMembers()
192+
{
193+
var source = Wrap(@"
194+
public interface IFirst { }
195+
public interface ISecond { }
196+
197+
public interface IBaseAggregate
198+
{
199+
IFirst First { get; }
200+
}
201+
202+
public interface IMyAggregate : IBaseAggregate
203+
{
204+
ISecond Second { get; }
205+
}
206+
207+
public static class Registration
208+
{
209+
public static void Configure(ContainerBuilder builder)
210+
{
211+
builder.RegisterAggregateService<IMyAggregate>();
212+
}
213+
}");
214+
215+
return Verify(GeneratorTestHarness.Run(source));
216+
}
217+
218+
[Fact]
219+
public Task MultipleAggregates_DeduplicatedAcrossCallSites()
220+
{
221+
var source = Wrap(@"
222+
public interface IMyService { }
223+
224+
public interface IMyAggregate
225+
{
226+
IMyService MyService { get; }
227+
}
228+
229+
public static class Registration
230+
{
231+
public static void Configure(ContainerBuilder builder, IComponentContext context)
232+
{
233+
// The same aggregate referenced from multiple call sites should emit only once.
234+
builder.RegisterAggregateService<IMyAggregate>();
235+
builder.RegisterAggregateService(typeof(IMyAggregate));
236+
AggregateServiceGenerator.CreateInstance<IMyAggregate>(context);
237+
}
238+
}");
239+
240+
return Verify(GeneratorTestHarness.Run(source));
241+
}
242+
243+
[Fact]
244+
public Task NoAggregateServices_EmitsNothing()
245+
{
246+
var source = Wrap(@"
247+
public static class Registration
248+
{
249+
public static void Configure(ContainerBuilder builder)
250+
{
251+
builder.RegisterType<object>();
252+
}
253+
}");
254+
255+
return Verify(GeneratorTestHarness.Run(source));
256+
}
257+
258+
/// <summary>
259+
/// Wraps a snippet in the using directives and namespace shared by all test sources.
260+
/// </summary>
261+
/// <param name="body">
262+
/// The body source to wrap.
263+
/// </param>
264+
/// <returns>
265+
/// The full compilation unit source.
266+
/// </returns>
267+
private static string Wrap(string body)
268+
{
269+
return @"using System;
270+
using Autofac;
271+
using Autofac.Extras.AggregateService;
272+
273+
namespace TestConsumer
274+
{
275+
" + body + @"
276+
}";
277+
}
278+
}

0 commit comments

Comments
 (0)