Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 4 additions & 4 deletions TUnit.Mocks.Analyzers.Tests/SealedClassMockAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public static class Mock
{
public static object Of<T>() => default!;
public static object Of<T>(int behavior) => default!;
public static object OfPartial<T>(params object[] args) => default!;
public static object OfPartial<T>(int behavior, params object[] args) => default!;
public static object Of<T>(int behavior, params object[] args) => default!;
public static object Of<T>(params object[] args) => default!;
}
}
""";
Expand Down Expand Up @@ -141,7 +141,7 @@ public void Test()
}

[Test]
public async Task Sealed_Class_Via_OfPartial_Reports_TM001()
public async Task Sealed_Class_With_Constructor_Args_Reports_TM001()
{
await Verifier.VerifyAnalyzerAsync(
MockStub + """
Expand All @@ -152,7 +152,7 @@ public class TestClass
{
public void Test()
{
{|#0:TUnit.Mocks.Mock.OfPartial<MyService>()|};
{|#0:TUnit.Mocks.Mock.Of<MyService>(0, "arg")|};
}
}
""",
Expand Down
8 changes: 4 additions & 4 deletions TUnit.Mocks.Analyzers.Tests/StructMockAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public static class Mock
{
public static object Of<T>() => default!;
public static object Of<T>(int behavior) => default!;
public static object OfPartial<T>(params object[] args) => default!;
public static object OfPartial<T>(int behavior, params object[] args) => default!;
public static object Of<T>(int behavior, params object[] args) => default!;
public static object Of<T>(params object[] args) => default!;
}
}
""";
Expand Down Expand Up @@ -144,7 +144,7 @@ public void Test()
}

[Test]
public async Task Struct_Via_OfPartial_Reports_TM002()
public async Task Struct_With_Constructor_Args_Reports_TM002()
{
await Verifier.VerifyAnalyzerAsync(
MockStub + """
Expand All @@ -155,7 +155,7 @@ public class TestClass
{
public void Test()
{
{|#0:TUnit.Mocks.Mock.OfPartial<MyStruct>()|};
{|#0:TUnit.Mocks.Mock.Of<MyStruct>(0, "arg")|};
}
}
""",
Expand Down
2 changes: 1 addition & 1 deletion TUnit.Mocks.Analyzers/SealedClassMockAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)

private static bool IsMockOfMethod(IMethodSymbol method)
{
return method.Name is "Of" or "OfPartial"
return method.Name is "Of"
&& method.ContainingType is { Name: "Mock" or "MockRepository", ContainingNamespace: { Name: "Mocks", ContainingNamespace: { Name: "TUnit", ContainingNamespace.IsGlobalNamespace: true } } }
&& method.IsGenericMethod;
}
Expand Down
2 changes: 1 addition & 1 deletion TUnit.Mocks.Analyzers/StructMockAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context)

private static bool IsMockOfMethod(IMethodSymbol method)
{
return method.Name is "Of" or "OfPartial"
return method.Name is "Of"
&& method.ContainingType is { Name: "Mock" or "MockRepository", ContainingNamespace: { Name: "Mocks", ContainingNamespace: { Name: "TUnit", ContainingNamespace.IsGlobalNamespace: true } } }
&& method.IsGenericMethod;
}
Expand Down
24 changes: 21 additions & 3 deletions TUnit.Mocks.SourceGenerator.Tests/MockGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ public class TestUsage
{
void M()
{
var mock = Mock.OfPartial<BaseService>();
var mock = Mock.Of<BaseService>();
}
}
""";
Expand Down Expand Up @@ -505,7 +505,7 @@ public class TestUsage
{
void M()
{
var mock = Mock.OfPartial<ExternalClient>();
var mock = Mock.Of<ExternalClient>();
}
}
""";
Expand Down Expand Up @@ -543,7 +543,7 @@ public class TestUsage
{
void M()
{
var mock = Mock.OfPartial<ServiceClient>();
var mock = Mock.Of<ServiceClient>();
}
}
""";
Expand Down Expand Up @@ -610,4 +610,22 @@ void M()

return VerifyGeneratorOutput(source);
}

[Test]
public Task GenerateMock_Attribute_With_Concrete_Class()
{
var source = """
using TUnit.Mocks;

[assembly: GenerateMock(typeof(MyService))]

public class MyService
{
public virtual string GetValue() => "real";
public virtual void DoWork() { }
}
""";

return VerifyGeneratorOutput(source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
internal static class MyService_PartialMockFactory
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
internal static void Register()
{
global::TUnit.Mocks.Mock.RegisterFactory<global::MyService>(Create);
}

private static global::TUnit.Mocks.Mock<global::MyService> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
var engine = new global::TUnit.Mocks.MockEngine<global::MyService>(behavior);
var impl = new MyService_MockImpl(engine);
engine.Raisable = impl;
var mock = new global::TUnit.Mocks.Mock<global::MyService>(impl, engine);
return mock;
}
}
}


// ===== FILE SEPARATOR =====

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
internal sealed class MyService_MockImpl : global::MyService, global::TUnit.Mocks.IRaisable, global::TUnit.Mocks.IMockObject
{
private readonly global::TUnit.Mocks.MockEngine<global::MyService> _engine;

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
global::TUnit.Mocks.IMock? global::TUnit.Mocks.IMockObject.MockWrapper { get; set; }

internal MyService_MockImpl(global::TUnit.Mocks.MockEngine<global::MyService> engine) : base()
{
_engine = engine;
}

public override string GetValue()
{
if (_engine.TryHandleCallWithReturn<string>(0, "GetValue", global::System.Array.Empty<object?>(), "", out var __result))
{
return __result;
}
return base.GetValue();
}

public override void DoWork()
{
if (_engine.TryHandleCall(1, "DoWork", global::System.Array.Empty<object?>()))
{
return;
}
base.DoWork();
}

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public void RaiseEvent(string eventName, object? args)
{
throw new global::System.InvalidOperationException($"No event named '{eventName}' exists on this mock.");
}
}
}


// ===== FILE SEPARATOR =====

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
public static class MyService_MockMemberExtensions
{
public static global::TUnit.Mocks.MockMethodCall<string> GetValue(this global::TUnit.Mocks.Mock<global::MyService> mock)
{
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.MockMethodCall<string>(global::TUnit.Mocks.Mock.GetEngine(mock), 0, "GetValue", matchers);
}

public static global::TUnit.Mocks.VoidMockMethodCall DoWork(this global::TUnit.Mocks.Mock<global::MyService> mock)
{
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.VoidMockMethodCall(global::TUnit.Mocks.Mock.GetEngine(mock), 1, "DoWork", matchers);
}
}
}


// ===== FILE SEPARATOR =====

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated;
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IReadWriter>(Create);
}

private static global::TUnit.Mocks.Mock<global::IReadWriter> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IReadWriter> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IReadWriter' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IReadWriter>(behavior);
var impl = new IReadWriter_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IAsyncService>(Create);
}

private static global::TUnit.Mocks.Mock<global::IAsyncService> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IAsyncService> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IAsyncService' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IAsyncService>(behavior);
var impl = new IAsyncService_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::INotifier>(Create);
}

private static global::TUnit.Mocks.Mock<global::INotifier> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::INotifier> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::INotifier' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::INotifier>(behavior);
var impl = new INotifier_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IRepository>(Create);
}

private static global::TUnit.Mocks.Mock<global::IRepository> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IRepository> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IRepository' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IRepository>(behavior);
var impl = new IRepository_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::TUnit.Mocks.Generated.IMyService_Mockable>(Create);
}

private static global::TUnit.Mocks.Mock<global::TUnit.Mocks.Generated.IMyService_Mockable> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::TUnit.Mocks.Generated.IMyService_Mockable> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::TUnit.Mocks.Generated.IMyService_Mockable' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::TUnit.Mocks.Generated.IMyService_Mockable>(behavior);
var impl = new IMyService_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::ITest>(Create);
}

private static global::TUnit.Mocks.Mock<global::ITest> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::ITest> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::ITest' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::ITest>(behavior);
var impl = new ITest_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IService>(Create);
}

private static global::TUnit.Mocks.Mock<global::IService> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IService> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IService' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IService>(behavior);
var impl = new IService_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IFoo>(Create);
}

private static global::TUnit.Mocks.Mock<global::IFoo> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IFoo> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IFoo' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IFoo>(behavior);
var impl = new IFoo_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IDictionary>(Create);
}

private static global::TUnit.Mocks.Mock<global::IDictionary> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IDictionary> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IDictionary' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IDictionary>(behavior);
var impl = new IDictionary_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <auto-generated/>
// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
Expand All @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IFormatter>(Create);
}

private static global::TUnit.Mocks.Mock<global::IFormatter> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IFormatter> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IFormatter' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IFormatter>(behavior);
var impl = new IFormatter_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IRepository>(Create);
}

private static global::TUnit.Mocks.Mock<global::IRepository> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IRepository> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IRepository' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IRepository>(behavior);
var impl = new IRepository_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IBufferProcessor>(Create);
}

private static global::TUnit.Mocks.Mock<global::IBufferProcessor> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IBufferProcessor> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IBufferProcessor' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IBufferProcessor>(behavior);
var impl = new IBufferProcessor_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::TUnit.Mocks.Generated.IServiceFactory_Mockable>(Create);
}

private static global::TUnit.Mocks.Mock<global::TUnit.Mocks.Generated.IServiceFactory_Mockable> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::TUnit.Mocks.Generated.IServiceFactory_Mockable> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::TUnit.Mocks.Generated.IServiceFactory_Mockable' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::TUnit.Mocks.Generated.IServiceFactory_Mockable>(behavior);
var impl = new IServiceFactory_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <auto-generated/>
// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
Expand All @@ -11,8 +11,9 @@ namespace TUnit.Mocks.Generated
global::TUnit.Mocks.Mock.RegisterFactory<global::IMyService>(Create);
}

private static global::TUnit.Mocks.Mock<global::IMyService> Create(global::TUnit.Mocks.MockBehavior behavior)
private static global::TUnit.Mocks.Mock<global::IMyService> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::IMyService' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::IMyService>(behavior);
var impl = new IMyService_MockImpl(engine);
engine.Raisable = impl;
Expand Down
Loading
Loading