Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,7 @@ namespace Mockolate;
sb.Append(' ').Append(parameter.Name);
}

sb.Append(")");
if (@delegate.GenericParameters is not null && @delegate.GenericParameters.Value.Count > 0)
{
foreach (GenericParameter gp in @delegate.GenericParameters.Value)
{
gp.AppendWhereConstraint(sb, "\t\t\t");
}
}

sb.AppendLine();
sb.Append(")").AppendLine();

sb.Append("\t\t\t=> CastToMockOrThrow(verify).Method(").Append(@delegate.GetUniqueNameString());

Expand All @@ -134,16 +125,7 @@ namespace Mockolate;
.AppendLine();
sb.Append("\t\t/// </summary>").AppendLine();
sb.Append("\t\tpublic VerificationResult<").Append(@class.ClassFullName).Append("> Invoked")
.Append("(IParameters parameters)");
if (@delegate.GenericParameters is not null && @delegate.GenericParameters.Value.Count > 0)
{
foreach (GenericParameter gp in @delegate.GenericParameters.Value)
{
gp.AppendWhereConstraint(sb, "\t\t\t");
}
}

sb.AppendLine();
.Append("(IParameters parameters)").AppendLine();

sb.Append("\t\t\t=> CastToMockOrThrow(verify).Method(").Append(@delegate.GetUniqueNameString());
sb.AppendLine(", parameters);");
Expand Down Expand Up @@ -607,10 +589,7 @@ property is
.Append(property.Name.EscapeForXmlDoc()).Append("\"/>.").AppendLine();
sb.Append("\t\t/// </summary>").AppendLine();
sb.Append("\t\tpublic IPropertySetup<").Append(property.Type.Fullname).Append("> ")
.Append(property.IndexerParameters is not null
? property.Name.Replace("[]",
$"[{string.Join(", ", property.IndexerParameters.Value.Select(p => $"IParameter<{p.Type.Fullname}> {p.Name}"))}]")
: property.Name).AppendLine();
.Append(property.Name).AppendLine();

sb.AppendLine("\t\t{");
sb.AppendLine("\t\t\tget");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ namespace Mockolate.Generated;
sb.Append("\t}").AppendLine();
sb.AppendLine();
}
else if (mockClass.Constructors?.Count > 0)
else if (mockClass.Constructors is not null)
{
foreach (Method constructor in mockClass.Constructors)
{
Expand Down
55 changes: 52 additions & 3 deletions Tests/Mockolate.SourceGenerators.Tests/GeneralTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,54 @@ await That(result.Sources).ContainsKey("MockForIListMyRecord.g.cs").WhoseValue
.Contains("internal class MockForIListMyRecord : System.Collections.Generic.IList<MyOtherCode.MyRecord>");
}

[Fact]
public async Task MultipleInterfacesWithSameName_ShouldAddSuffixToSetupAndVerifyMethods()
{
GeneratorResult result = Generator
.Run("""
using System.Collections.Generic;

namespace MyCode
{
public class Program
{
public static void Main(string[] args)
{
var x = Mockolate.Mock.Create<IMyInterface, MyCode.N1.IMyInterface, MyCode.N2.IMyInterface>();
}
}

public interface IMyInterface
{
new void MyMethod(int v1);
}
}

namespace MyCode.N1
{
public interface IMyInterface
{
new void MyMethod(int v1);
Comment thread
vbreuss marked this conversation as resolved.
Outdated
}
}

namespace MyCode.N2
{
public interface IMyInterface
{
new void MyMethod(int v1);
Comment thread
vbreuss marked this conversation as resolved.
Outdated
}
}

""", typeof(IList<>));

await That(result.Diagnostics).IsEmpty();

await That(result.Sources).ContainsKey("MockForIMyInterface_IMyInterface_IMyInterfaceExtensions.g.cs")
.WhoseValue
.Contains("public IMockSetup<MyCode.N2.IMyInterface> SetupIMyInterface__2Mock");
}

[Fact]
public async Task ObsoleteAttributes_ShouldBeRepeatedInMock()
{
Expand Down Expand Up @@ -394,13 +442,13 @@ public interface IMyService
)]
event EventHandler<int> MyEvent;
}

public enum MyEnum
{
Value1 = 1,
Value2 = 2
}

[Flags]
public enum MyFlagEnum
{
Expand Down Expand Up @@ -449,7 +497,8 @@ public CustomAttribute(
public MyFlagEnum EnumParam { get; set; }
public string[] ArrayParam { get; set; }
}
""", typeof(AllowNullAttribute), typeof(IDataParameter), typeof(LocalizableAttribute), typeof(AttributeUsageAttribute));
""", typeof(AllowNullAttribute), typeof(IDataParameter), typeof(LocalizableAttribute),
typeof(AttributeUsageAttribute));

await That(result.Sources).ContainsKey("MockForIMyService.g.cs").WhoseValue
.Contains("""
Expand Down
69 changes: 59 additions & 10 deletions Tests/Mockolate.SourceGenerators.Tests/MockGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ await ThatAll(
}

[Fact]
public async Task WhenUsingMockCreateFromOtherNamespace_ShouldNotBeIncluded()
public async Task WhenUsingCustomMockGeneratorAttribute_ShouldNotBeIncluded()
{
GeneratorResult result = Generator
.Run("""
Expand All @@ -182,10 +182,59 @@ public interface IMyInterface { }

public class Mock
{
public static Mock<T> Create<T>() => new Mock<T>();
[Mockolate.MockGenerator]
public static T Create<T>() => default(T)!;
}
}
""");

public class Mock<T>{ }
await ThatAll(
That(result.Sources.Keys).IsEqualTo([
"Mock.g.cs",
"MockBehaviorExtensions.g.cs",
"MockForIMyInterface.g.cs",
"MockForIMyInterfaceExtensions.g.cs",
"MockGeneratorAttribute.g.cs",
"MockRegistration.g.cs",
]).InAnyOrder().IgnoringCase(),
That(result.Diagnostics).IsEmpty()
);
}

[Fact]
public async Task WhenUsingIncorrectMockGeneratorAttribute_ShouldNotBeIncluded()
{
GeneratorResult result = Generator
.Run("""
using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyCode
{
public class Program
{
public static void Main(string[] args)
{
_ = Mock.Create<IMyInterface>();
}
}

public interface IMyInterface { }

public class Mock
{
[Mockolate.Incorrect.MockGenerator]
public static T Create<T>() => default(T)!;
}
}

namespace Mockolate.Incorrect
{
[AttributeUsage(AttributeTargets.Method)]
internal class MockGeneratorAttribute : Attribute
{
}
}
""");

Expand Down Expand Up @@ -293,13 +342,13 @@ public class MyOtherService { }
""");

await That(result.Sources.Keys).IsEqualTo([
"Mock.g.cs",
"MockBehaviorExtensions.g.cs",
"MockGeneratorAttribute.g.cs",
"MockForIMyInterface1Extensions.g.cs",
"MockForIMyInterface2Extensions.g.cs",
"MockRegistration.g.cs",
]).InAnyOrder();
"Mock.g.cs",
"MockBehaviorExtensions.g.cs",
"MockGeneratorAttribute.g.cs",
"MockForIMyInterface1Extensions.g.cs",
"MockForIMyInterface2Extensions.g.cs",
"MockRegistration.g.cs",
]).InAnyOrder();
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ public static void Main(string[] args)
_ = Mock.Create<DoSomething>();
}

public delegate int DoSomething(int x, int y);
public delegate int DoSomething(int x, int y, out bool success);
}
""");

await That(result.Sources)
.ContainsKey("MockForProgramDoSomethingExtensions.g.cs").WhoseValue
.Contains("""
public IReturnMethodSetup<int, int, int> Delegate(IParameter<int>? x, IParameter<int>? y)
public IReturnMethodSetup<int, int, int, bool> Delegate(IParameter<int>? x, IParameter<int>? y, IOutParameter<bool> success)
{
var methodSetup = new ReturnMethodSetup<int, int, int>("MyCode.Program.DoSomething.Invoke", new NamedParameter("x", (IParameter)(x ?? It.IsNull<int>())), new NamedParameter("y", (IParameter)(y ?? It.IsNull<int>())));
var methodSetup = new ReturnMethodSetup<int, int, int, bool>("MyCode.Program.DoSomething.Invoke", new NamedParameter("x", (IParameter)(x ?? It.IsNull<int>())), new NamedParameter("y", (IParameter)(y ?? It.IsNull<int>())), new NamedParameter("success", (IParameter)(success)));
CastToMockRegistrationOrThrow(setup).SetupMethod(methodSetup);
return methodSetup;
}
""").IgnoringNewlineStyle().And
.Contains("""
public VerificationResult<MyCode.Program.DoSomething> Invoked(IParameter<int>? x, IParameter<int>? y)
=> CastToMockOrThrow(verify).Method("MyCode.Program.DoSomething.Invoke", new NamedParameter("x", (IParameter)(x ?? It.IsNull<int>())), new NamedParameter("y", (IParameter)(y ?? It.IsNull<int>())));
public VerificationResult<MyCode.Program.DoSomething> Invoked(IParameter<int>? x, IParameter<int>? y, IVerifyOutParameter<bool> success)
=> CastToMockOrThrow(verify).Method("MyCode.Program.DoSomething.Invoke", new NamedParameter("x", (IParameter)(x ?? It.IsNull<int>())), new NamedParameter("y", (IParameter)(y ?? It.IsNull<int>())), new NamedParameter("success", (IParameter)(success)));
""").IgnoringNewlineStyle();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,21 @@ public class Program
public static void Main(string[] args)
{
_ = Mock.Create<MyService, IMyOtherService>();
_ = Mock.Create<MyProtectedService>();
}
}

public class MyService
{
public virtual event EventHandler SomeEvent;
public event EventHandler? SomeOtherEvent;
protected virtual event EventHandler SomeProtectedEvent;
}

public class MyProtectedService
{
protected virtual event EventHandler SomeProtectedEvent;
}

public interface IMyOtherService
{
Expand Down Expand Up @@ -351,7 +357,7 @@ public static void Main(string[] args)
public interface IMyService
{
int this[int index] { get; set; }
int this[int index, bool isReadOnly] { get; }
int this[int index, bool? isReadOnly] { get; }
int this[int index, string isWriteOnly] { set; }
}
""");
Expand Down Expand Up @@ -382,8 +388,8 @@ public int this[int index]
}
""").IgnoringNewlineStyle().And
.Contains("""
/// <inheritdoc cref="MyCode.IMyService.this[int, bool]" />
public int this[int index, bool isReadOnly]
/// <inheritdoc cref="MyCode.IMyService.this[int, bool?]" />
public int this[int index, bool? isReadOnly]
{
get
{
Expand Down Expand Up @@ -427,16 +433,22 @@ public class Program
public static void Main(string[] args)
{
_ = Mock.Create<MyService, IMyOtherService>();
_ = Mock.Create<MyProtectedService>();
}
}

public class MyService
{
public virtual int this[int index] { get; set; }
protected virtual int this[int index, bool isReadOnly] { get; }
protected virtual int this[int index, string isWriteOnly] { set; }
public int this[int index, long isNotVirtual] { get; set; }
}

public class MyProtectedService
{
protected virtual int this[int index, bool? isReadOnly] { get; set; }
}

public interface IMyOtherService
{
Expand Down Expand Up @@ -931,9 +943,10 @@ public class Program
public static void Main(string[] args)
{
_ = Mock.Create<MyService, IMyOtherService>();
_ = Mock.Create<MyProtectedService>();
}
}

public class MyService
{
public virtual void MyMethod1(int index, ref int value1, out bool flag)
Expand All @@ -946,6 +959,14 @@ protected virtual bool MyMethod2(int index, bool isReadOnly, ref int value1, out
}
public void MyNonVirtualMethod();
}

public class MyProtectedService
{
protected virtual bool MyMethod(int index, bool isReadOnly, ref int value1, out bool flag)
{
flag = true;
}
Comment thread
vbreuss marked this conversation as resolved.
}

public interface IMyOtherService
{
Expand Down Expand Up @@ -1458,9 +1479,10 @@ public class Program
public static void Main(string[] args)
{
_ = Mock.Create<MyService, IMyOtherService>();
_ = Mock.Create<MyProtectedService>();
}
}

public class MyService
{
public virtual int SomeProperty1 { protected get; set; }
Expand All @@ -1469,6 +1491,11 @@ public class MyService
protected virtual bool? SomeWriteOnlyProperty { set; }
public bool? SomeNonVirtualProperty { get; set; }
}

public class MyProtectedService
{
protected virtual bool? SomeProperty { get; set; }
}

public interface IMyOtherService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static class Generator
"CS1061" /* 'type' does not contain a definition for 'name' and no accessible extension method 'name' accepting a first argument of type 'type' could be found (are you missing a using directive or an assembly reference?). */,
// TODO: Remove the following errors when tests work with extension syntax
"CS0106" /* The modifier 'public' is not valid for this item */,
"CS0109" /* The member 'member' does not hide an inherited member. The new keyword is not required */,
"CS0116" /* A namespace cannot directly contain members such as fields or methods */,
"CS1520" /* Method must have a return type */,
"CS0710" /* Static classes cannot have instance constructors */,
Expand Down
Loading
Loading