Skip to content

Commit f85a77d

Browse files
committed
#340 updated changelog, added a test, time for a merge
1 parent 198c043 commit f85a77d

File tree

3 files changed

+260
-1
lines changed

3 files changed

+260
-1
lines changed

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [8.3.1] - 2024-09-30
9+
10+
### Fixed
11+
12+
- Addressed a rare naming issue with projects referencing Rocks and each other (issue [#340](https://github.com/JasonBock/Rocks/issues/340))
13+
814
## [8.3.0] - 2024-07-24
915

1016
### Added

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
<Nullable>enable</Nullable>
1515
<TargetFramework>net8.0</TargetFramework>
1616
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
17-
<Version>8.3.1-alpha.1</Version>
17+
<Version>8.3.1</Version>
1818
</PropertyGroup>
1919
</Project>

src/Rocks.Tests/Generators/NamingGeneratorTests.cs

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,259 @@ namespace Rocks.Tests.Generators;
66

77
public static class NamingGeneratorTests
88
{
9+
[Test]
10+
public static async Task GenerateWhenBothCompilationsUseRocksAndSourceMakesInternalsVisibleAsync()
11+
{
12+
var source =
13+
"""
14+
using Rocks;
15+
using System.Runtime.CompilerServices;
16+
17+
[assembly: Rock(typeof(Class1), BuildType.Create)]
18+
[assembly: InternalsVisibleTo("TestProject")]
19+
20+
public class Class1 { }
21+
""";
22+
var sourceReferences = Shared.References.Value
23+
.Cast<MetadataReference>()
24+
.ToList();
25+
var sourceSyntaxTree = CSharpSyntaxTree.ParseText(source);
26+
var sourceCompilation = CSharpCompilation.Create("Source", [sourceSyntaxTree],
27+
sourceReferences,
28+
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
29+
GeneratorDriver sourceDriver = CSharpGeneratorDriver.Create(
30+
generators: [(new RockGenerator()).AsSourceGenerator()]);
31+
32+
sourceDriver = sourceDriver.RunGeneratorsAndUpdateCompilation(sourceCompilation, out var newSourceCompilation, out _);
33+
var sourceReference = newSourceCompilation.ToMetadataReference()!;
34+
sourceReferences.Add(sourceReference);
35+
36+
var code =
37+
"""
38+
using Rocks;
39+
40+
[assembly: Rock(typeof(Class1), BuildType.Create)]
41+
""";
42+
43+
var generatedCode =
44+
"""
45+
// <auto-generated/>
46+
47+
#pragma warning disable CS8618
48+
#pragma warning disable CS8633
49+
#pragma warning disable CS8714
50+
#pragma warning disable CS8775
51+
52+
#nullable enable
53+
54+
using Rocks.Extensions;
55+
56+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
57+
internal sealed class Class1CreateExpectations2
58+
: global::Rocks.Expectations
59+
{
60+
internal sealed class Handler0
61+
: global::Rocks.Handler<global::System.Func<string?>, string?>
62+
{ }
63+
private global::Rocks.Handlers<global::Class1CreateExpectations2.Handler0>? @handlers0;
64+
internal sealed class Handler1
65+
: global::Rocks.Handler<global::System.Func<object?, bool>, bool>
66+
{
67+
public global::Rocks.Argument<object?> @obj { get; set; }
68+
}
69+
private global::Rocks.Handlers<global::Class1CreateExpectations2.Handler1>? @handlers1;
70+
internal sealed class Handler2
71+
: global::Rocks.Handler<global::System.Func<int>, int>
72+
{ }
73+
private global::Rocks.Handlers<global::Class1CreateExpectations2.Handler2>? @handlers2;
74+
75+
public override void Verify()
76+
{
77+
if (this.WasInstanceInvoked)
78+
{
79+
var failures = new global::System.Collections.Generic.List<string>();
80+
81+
if (this.handlers0 is not null) { failures.AddRange(this.Verify(this.handlers0, 0)); }
82+
if (this.handlers1 is not null) { failures.AddRange(this.Verify(this.handlers1, 1)); }
83+
if (this.handlers2 is not null) { failures.AddRange(this.Verify(this.handlers2, 2)); }
84+
85+
if (failures.Count > 0)
86+
{
87+
throw new global::Rocks.Exceptions.VerificationException(failures);
88+
}
89+
}
90+
}
91+
92+
private sealed class Mock
93+
: global::Class1
94+
{
95+
public Mock(global::Class1CreateExpectations2 @expectations)
96+
{
97+
this.Expectations = @expectations;
98+
}
99+
100+
[global::Rocks.MemberIdentifier(0)]
101+
public override string? ToString()
102+
{
103+
if (this.Expectations.handlers0 is not null)
104+
{
105+
var @handler = this.Expectations.handlers0.First;
106+
@handler.CallCount++;
107+
var @result = @handler.Callback is not null ?
108+
@handler.Callback() : @handler.ReturnValue;
109+
return @result!;
110+
}
111+
else
112+
{
113+
return base.ToString();
114+
}
115+
}
116+
117+
[global::Rocks.MemberIdentifier(1)]
118+
public override bool Equals(object? @obj)
119+
{
120+
if (this.Expectations.handlers1 is not null)
121+
{
122+
foreach (var @handler in this.Expectations.handlers1)
123+
{
124+
if (@handler.@obj.IsValid(@obj!))
125+
{
126+
@handler.CallCount++;
127+
var @result = @handler.Callback is not null ?
128+
@handler.Callback(@obj!) : @handler.ReturnValue;
129+
return @result!;
130+
}
131+
}
132+
133+
throw new global::Rocks.Exceptions.ExpectationException($"No handlers match for {this.GetType().GetMemberDescription(1)}");
134+
}
135+
else
136+
{
137+
return base.Equals(obj: @obj!);
138+
}
139+
}
140+
141+
[global::Rocks.MemberIdentifier(2)]
142+
public override int GetHashCode()
143+
{
144+
if (this.Expectations.handlers2 is not null)
145+
{
146+
var @handler = this.Expectations.handlers2.First;
147+
@handler.CallCount++;
148+
var @result = @handler.Callback is not null ?
149+
@handler.Callback() : @handler.ReturnValue;
150+
return @result!;
151+
}
152+
else
153+
{
154+
return base.GetHashCode();
155+
}
156+
}
157+
158+
private global::Class1CreateExpectations2 Expectations { get; }
159+
}
160+
161+
internal sealed class MethodExpectations
162+
{
163+
internal MethodExpectations(global::Class1CreateExpectations2 expectations) =>
164+
this.Expectations = expectations;
165+
166+
internal new global::Class1CreateExpectations2.Adornments.AdornmentsForHandler0 ToString()
167+
{
168+
global::Rocks.Exceptions.ExpectationException.ThrowIf(this.Expectations.WasInstanceInvoked);
169+
var handler = new global::Class1CreateExpectations2.Handler0();
170+
if (this.Expectations.handlers0 is null) { this.Expectations.handlers0 = new(handler); }
171+
else { this.Expectations.handlers0.Add(handler); }
172+
return new(handler);
173+
}
174+
175+
internal global::Class1CreateExpectations2.Adornments.AdornmentsForHandler1 Equals(global::Rocks.Argument<object?> @obj)
176+
{
177+
global::Rocks.Exceptions.ExpectationException.ThrowIf(this.Expectations.WasInstanceInvoked);
178+
global::System.ArgumentNullException.ThrowIfNull(@obj);
179+
180+
var @handler = new global::Class1CreateExpectations2.Handler1
181+
{
182+
@obj = @obj,
183+
};
184+
185+
if (this.Expectations.handlers1 is null) { this.Expectations.handlers1 = new(@handler); }
186+
else { this.Expectations.handlers1.Add(@handler); }
187+
return new(@handler);
188+
}
189+
190+
internal new global::Class1CreateExpectations2.Adornments.AdornmentsForHandler2 GetHashCode()
191+
{
192+
global::Rocks.Exceptions.ExpectationException.ThrowIf(this.Expectations.WasInstanceInvoked);
193+
var handler = new global::Class1CreateExpectations2.Handler2();
194+
if (this.Expectations.handlers2 is null) { this.Expectations.handlers2 = new(handler); }
195+
else { this.Expectations.handlers2.Add(handler); }
196+
return new(handler);
197+
}
198+
199+
private global::Class1CreateExpectations2 Expectations { get; }
200+
}
201+
202+
internal global::Class1CreateExpectations2.MethodExpectations Methods { get; }
203+
204+
internal Class1CreateExpectations2() =>
205+
(this.Methods) = (new(this));
206+
207+
internal global::Class1 Instance()
208+
{
209+
if (!this.WasInstanceInvoked)
210+
{
211+
this.WasInstanceInvoked = true;
212+
var @mock = new Mock(this);
213+
this.MockType = @mock.GetType();
214+
return @mock;
215+
}
216+
else
217+
{
218+
throw new global::Rocks.Exceptions.NewMockInstanceException("Can only create a new mock once.");
219+
}
220+
}
221+
222+
internal static class Adornments
223+
{
224+
public interface IAdornmentsForClass1<TAdornments>
225+
: global::Rocks.IAdornments<TAdornments>
226+
where TAdornments : IAdornmentsForClass1<TAdornments>
227+
{ }
228+
229+
public sealed class AdornmentsForHandler0
230+
: global::Rocks.Adornments<AdornmentsForHandler0, global::Class1CreateExpectations2.Handler0, global::System.Func<string?>, string?>, IAdornmentsForClass1<AdornmentsForHandler0>
231+
{
232+
public AdornmentsForHandler0(global::Class1CreateExpectations2.Handler0 handler)
233+
: base(handler) { }
234+
}
235+
public sealed class AdornmentsForHandler1
236+
: global::Rocks.Adornments<AdornmentsForHandler1, global::Class1CreateExpectations2.Handler1, global::System.Func<object?, bool>, bool>, IAdornmentsForClass1<AdornmentsForHandler1>
237+
{
238+
public AdornmentsForHandler1(global::Class1CreateExpectations2.Handler1 handler)
239+
: base(handler) { }
240+
}
241+
public sealed class AdornmentsForHandler2
242+
: global::Rocks.Adornments<AdornmentsForHandler2, global::Class1CreateExpectations2.Handler2, global::System.Func<int>, int>, IAdornmentsForClass1<AdornmentsForHandler2>
243+
{
244+
public AdornmentsForHandler2(global::Class1CreateExpectations2.Handler2 handler)
245+
: base(handler) { }
246+
}
247+
}
248+
}
249+
250+
#pragma warning restore CS8618
251+
#pragma warning restore CS8633
252+
#pragma warning restore CS8714
253+
#pragma warning restore CS8775
254+
""";
255+
256+
await TestAssistants.RunGeneratorAsync<RockGenerator>(code,
257+
[(typeof(RockGenerator), "Class1_Rock_Create.g.cs", generatedCode)],
258+
[],
259+
additionalReferences: sourceReferences);
260+
}
261+
9262
[Test]
10263
public static async Task GenerateWhenBothCompilationsUseRocksAsync()
11264
{

0 commit comments

Comments
 (0)