Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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