diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt index c060b8b02d..76d191b179 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -110,39 +110,43 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IReadWriter_Write_M2_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup + public readonly struct IReadWriter_Write_M2_TypedSetup { private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; internal IReadWriter_Write_M2_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IReadWriter_Write_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + /// + public IReadWriter_Write_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IReadWriter_Write_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IReadWriter_Write_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IReadWriter_Write_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IReadWriter_Write_M2_TypedSetup Then() { _inner.Then(); return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) + public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) + public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt index 8431b86c75..2b556f7a56 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -156,141 +156,155 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_GetValueAsync_M0_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IAsyncService_GetValueAsync_M0_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IAsyncService_GetValueAsync_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IAsyncService_GetValueAsync_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + /// + public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IAsyncService_GetValueAsync_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IAsyncService_GetValueAsync_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IAsyncService_GetValueAsync_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IAsyncService_GetValueAsync_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IAsyncService_GetValueAsync_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IAsyncService_GetValueAsync_M0_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!)); + _inner.Returns(args => factory((string)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_ComputeAsync_M2_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IAsyncService_ComputeAsync_M2_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IAsyncService_ComputeAsync_M2_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(int value) => _inner.Returns(value); + public IAsyncService_ComputeAsync_M2_TypedSetup Returns(int value) { _inner.Returns(value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params int[] values) => _inner.ReturnsSequentially(values); + public IAsyncService_ComputeAsync_M2_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IAsyncService_ComputeAsync_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IAsyncService_ComputeAsync_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IAsyncService_ComputeAsync_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IAsyncService_ComputeAsync_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + /// + public IAsyncService_ComputeAsync_M2_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((int)args[0]!)); + _inner.Returns(args => factory((int)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!)); + _inner.Callback(args => callback((int)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_InitializeAsync_M3_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup + public readonly struct IAsyncService_InitializeAsync_M3_TypedSetup { private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; internal IAsyncService_InitializeAsync_M3_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IAsyncService_InitializeAsync_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + /// + public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IAsyncService_InitializeAsync_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IAsyncService_InitializeAsync_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IAsyncService_InitializeAsync_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IAsyncService_InitializeAsync_M3_TypedSetup Then() { _inner.Then(); return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) + public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((global::System.Threading.CancellationToken)args[0]!)); + _inner.Callback(args => callback((global::System.Threading.CancellationToken)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) + public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((global::System.Threading.CancellationToken)args[0]!)); + _inner.Throws(args => exceptionFactory((global::System.Threading.CancellationToken)args[0]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt index 92ae10deb5..72a7e0786e 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt @@ -1,4 +1,35 @@ -// +// +#nullable enable + +namespace TUnit.Mocks.Generated +{ + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public readonly struct INotifier_MockEvents + { + internal readonly global::TUnit.Mocks.MockEngine Engine; + + internal INotifier_MockEvents(global::TUnit.Mocks.MockEngine engine) => Engine = engine; + } + + public static class INotifier_MockEventsExtensions + { + extension(global::TUnit.Mocks.Mock mock) + { + public INotifier_MockEvents Events => new(mock.Engine); + } + + extension(INotifier_MockEvents events) + { + public global::TUnit.Mocks.EventSubscriptionAccessor ItemAdded + => new(events.Engine, "ItemAdded"); + } + } +} + + +// ===== FILE SEPARATOR ===== + +// #nullable enable namespace TUnit.Mocks.Generated @@ -129,40 +160,61 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct INotifier_Notify_M0_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup + public readonly struct INotifier_Notify_M0_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup, global::TUnit.Mocks.Setup.IVoidSetupChain { private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; internal INotifier_Notify_M0_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws() => _inner.Throws(); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + global::TUnit.Mocks.Setup.IVoidMethodSetup global::TUnit.Mocks.Setup.IVoidSetupChain.Then() { _inner.Then(); return this; } + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + /// + public INotifier_Notify_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public INotifier_Notify_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public INotifier_Notify_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public INotifier_Notify_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public INotifier_Notify_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public INotifier_Notify_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public INotifier_Notify_M0_TypedSetup Then() { _inner.Then(); return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) + public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) + public INotifier_Notify_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } + + /// Auto-raise the ItemAdded event when this method is called. + public INotifier_Notify_M0_TypedSetup RaisesItemAdded(string e) { _inner.Raises("ItemAdded", (object?)e); return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt index 66791437ce..24e8949a51 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt @@ -1,4 +1,35 @@ -// +// +#nullable enable + +namespace TUnit.Mocks.Generated +{ + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public readonly struct IService_MockEvents + { + internal readonly global::TUnit.Mocks.MockEngine Engine; + + internal IService_MockEvents(global::TUnit.Mocks.MockEngine engine) => Engine = engine; + } + + public static class IService_MockEventsExtensions + { + extension(global::TUnit.Mocks.Mock mock) + { + public IService_MockEvents Events => new(mock.Engine); + } + + extension(IService_MockEvents events) + { + public global::TUnit.Mocks.EventSubscriptionAccessor StatusChanged + => new(events.Engine, "StatusChanged"); + } + } +} + + +// ===== FILE SEPARATOR ===== + +// #nullable enable namespace TUnit.Mocks.Generated @@ -171,91 +202,138 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IService_GetAsync_M3_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IService_GetAsync_M3_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup, global::TUnit.Mocks.Setup.ISetupChain { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IService_GetAsync_M3_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(string value) => _inner.Returns(value); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(global::System.Func factory) => _inner.Returns(factory); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws() => _inner.Throws(); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(global::System.Func factory) => _inner.Returns(factory); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + global::TUnit.Mocks.Setup.IMethodSetup global::TUnit.Mocks.Setup.ISetupChain.Then() { _inner.Then(); return this; } + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + /// + public IService_GetAsync_M3_TypedSetup Returns(string value) { _inner.Returns(value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IService_GetAsync_M3_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IService_GetAsync_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IService_GetAsync_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IService_GetAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IService_GetAsync_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IService_GetAsync_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IService_GetAsync_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IService_GetAsync_M3_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((int)args[0]!)); + _inner.Returns(args => factory((int)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!)); + _inner.Callback(args => callback((int)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IService_GetAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!)); + return this; } + + /// Auto-raise the StatusChanged event when this method is called. + public IService_GetAsync_M3_TypedSetup RaisesStatusChanged(string e) { _inner.Raises("StatusChanged", (object?)e); return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IService_Process_M4_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup + public readonly struct IService_Process_M4_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup, global::TUnit.Mocks.Setup.IVoidSetupChain { private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; internal IService_Process_M4_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws() => _inner.Throws(); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + global::TUnit.Mocks.Setup.IVoidMethodSetup global::TUnit.Mocks.Setup.IVoidSetupChain.Then() { _inner.Then(); return this; } + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + + /// + public IService_Process_M4_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IService_Process_M4_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IService_Process_M4_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IService_Process_M4_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IService_Process_M4_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IService_Process_M4_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IService_Process_M4_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IService_Process_M4_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IService_Process_M4_TypedSetup Then() { _inner.Then(); return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) + public IService_Process_M4_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) + public IService_Process_M4_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } + + /// Auto-raise the StatusChanged event when this method is called. + public IService_Process_M4_TypedSetup RaisesStatusChanged(string e) { _inner.Raises("StatusChanged", (object?)e); return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt index f0b0ab4d1c..8d5136761f 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -109,90 +109,99 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IDictionary_TryGetValue_M0_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IDictionary_TryGetValue_M0_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IDictionary_TryGetValue_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(bool value) => _inner.Returns(value); + public IDictionary_TryGetValue_M0_TypedSetup Returns(bool value) { _inner.Returns(value); return this; } + /// + public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IDictionary_TryGetValue_M0_TypedSetup ReturnsSequentially(params bool[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params bool[] values) => _inner.ReturnsSequentially(values); + public IDictionary_TryGetValue_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IDictionary_TryGetValue_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IDictionary_TryGetValue_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IDictionary_TryGetValue_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IDictionary_TryGetValue_M0_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!)); + _inner.Returns(args => factory((string)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IDictionary_Swap_M1_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup + public readonly struct IDictionary_Swap_M1_TypedSetup { private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; internal IDictionary_Swap_M1_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IDictionary_Swap_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + /// + public IDictionary_Swap_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IDictionary_Swap_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IDictionary_Swap_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IDictionary_Swap_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IDictionary_Swap_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.IVoidSetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IDictionary_Swap_M1_TypedSetup Then() { _inner.Then(); return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Callback(global::System.Action callback) + public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.IVoidSetupChain Throws(global::System.Func exceptionFactory) + public IDictionary_Swap_M1_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt index 1cff4a5e7c..382d2c901d 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -124,206 +124,226 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M0_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IFormatter_Format_M0_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IFormatter_Format_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IFormatter_Format_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + /// + public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IFormatter_Format_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IFormatter_Format_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IFormatter_Format_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IFormatter_Format_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IFormatter_Format_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IFormatter_Format_M0_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!)); + _inner.Returns(args => factory((string)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M1_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IFormatter_Format_M1_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IFormatter_Format_M1_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IFormatter_Format_M1_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + /// + public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M1_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IFormatter_Format_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IFormatter_Format_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IFormatter_Format_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IFormatter_Format_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IFormatter_Format_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IFormatter_Format_M1_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((int)args[0]!)); + _inner.Returns(args => factory((int)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!)); + _inner.Callback(args => callback((int)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M1_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M2_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IFormatter_Format_M2_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IFormatter_Format_M2_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IFormatter_Format_M2_TypedSetup Returns(string value) { _inner.Returns(value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IFormatter_Format_M2_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IFormatter_Format_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IFormatter_Format_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IFormatter_Format_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IFormatter_Format_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IFormatter_Format_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IFormatter_Format_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + /// + public IFormatter_Format_M2_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!, (string)args[1]!)); + _inner.Returns(args => factory((string)args[0]!, (string)args[1]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!, (string)args[1]!)); + _inner.Callback(args => callback((string)args[0]!, (string)args[1]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M2_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M3_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IFormatter_Format_M3_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IFormatter_Format_M3_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IFormatter_Format_M3_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + /// + public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M3_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IFormatter_Format_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IFormatter_Format_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IFormatter_Format_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IFormatter_Format_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IFormatter_Format_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IFormatter_Format_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IFormatter_Format_M3_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + _inner.Returns(args => factory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!, (string)args[1]!, (string)args[2]!)); + _inner.Callback(args => callback((string)args[0]!, (string)args[1]!, (string)args[2]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M3_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt index 04ca247ac5..ea0fcfae1b 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -110,104 +110,114 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct ICalculator_Add_M0_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct ICalculator_Add_M0_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal ICalculator_Add_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(int value) => _inner.Returns(value); + public ICalculator_Add_M0_TypedSetup Returns(int value) { _inner.Returns(value); return this; } + /// + public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public ICalculator_Add_M0_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params int[] values) => _inner.ReturnsSequentially(values); + public ICalculator_Add_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public ICalculator_Add_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public ICalculator_Add_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public ICalculator_Add_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public ICalculator_Add_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public ICalculator_Add_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public ICalculator_Add_M0_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public ICalculator_Add_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + return this; } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct ICalculator_Subtract_M1_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct ICalculator_Subtract_M1_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal ICalculator_Subtract_M1_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(int value) => _inner.Returns(value); + public ICalculator_Subtract_M1_TypedSetup Returns(int value) { _inner.Returns(value); return this; } + /// + public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public ICalculator_Subtract_M1_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params int[] values) => _inner.ReturnsSequentially(values); + public ICalculator_Subtract_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public ICalculator_Subtract_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public ICalculator_Subtract_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public ICalculator_Subtract_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public ICalculator_Subtract_M1_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt index cdbacbccec..6f5096a4c6 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -82,53 +82,58 @@ namespace TUnit.Mocks.Generated } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IGreeter_Greet_M0_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup + public readonly struct IGreeter_Greet_M0_TypedSetup { private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; internal IGreeter_Greet_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(string value) => _inner.Returns(value); + public IGreeter_Greet_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + /// + public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IGreeter_Greet_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); + public IGreeter_Greet_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws() where TException : global::System.Exception, new() => _inner.Throws(); + public IGreeter_Greet_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Exception exception) => _inner.Throws(exception); + public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) => _inner.Callback(callback); + public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) => _inner.Returns(factory); + public IGreeter_Greet_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); + public IGreeter_Greet_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain Raises(string eventName, object? args = null) => _inner.Raises(eventName, args); + public IGreeter_Greet_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); + public IGreeter_Greet_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } /// - public global::TUnit.Mocks.Setup.ISetupChain TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + public IGreeter_Greet_M0_TypedSetup Then() { _inner.Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Returns(global::System.Func factory) + public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) { - return _inner.Returns(args => factory((string)args[0]!)); + _inner.Returns(args => factory((string)args[0]!)); + return this; } /// Execute a typed callback using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Callback(global::System.Action callback) + public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) { - return _inner.Callback(args => callback((string)args[0]!)); + _inner.Callback(args => callback((string)args[0]!)); + return this; } /// Configure a typed computed exception using the actual method parameters. - public global::TUnit.Mocks.Setup.ISetupChain Throws(global::System.Func exceptionFactory) + public IGreeter_Greet_M0_TypedSetup Throws(global::System.Func exceptionFactory) { - return _inner.Throws(args => exceptionFactory((string)args[0]!)); + _inner.Throws(args => exceptionFactory((string)args[0]!)); + return this; } } } diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockEventsBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockEventsBuilder.cs new file mode 100644 index 0000000000..2a5c11b06a --- /dev/null +++ b/TUnit.Mocks.SourceGenerator/Builders/MockEventsBuilder.cs @@ -0,0 +1,57 @@ +using TUnit.Mocks.SourceGenerator.Models; + +namespace TUnit.Mocks.SourceGenerator.Builders; + +internal static class MockEventsBuilder +{ + public static string Build(MockTypeModel model) + { + var writer = new CodeWriter(); + var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); + + writer.AppendLine("// "); + writer.AppendLine("#nullable enable"); + writer.AppendLine(); + + using (writer.Block("namespace TUnit.Mocks.Generated")) + { + // Lightweight struct holding engine reference — no allocation + writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); + using (writer.Block($"public readonly struct {safeName}_MockEvents")) + { + writer.AppendLine($"internal readonly global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> Engine;"); + writer.AppendLine(); + writer.AppendLine($"internal {safeName}_MockEvents(global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> engine) => Engine = engine;"); + } + + writer.AppendLine(); + + using (writer.Block($"public static class {safeName}_MockEventsExtensions")) + { + // Extension property on Mock — non-nullable, only present when type has events + using (writer.Block($"extension(global::TUnit.Mocks.Mock<{model.FullyQualifiedName}> mock)")) + { + writer.AppendLine($"public {safeName}_MockEvents Events => new(mock.Engine);"); + } + + writer.AppendLine(); + + // Per-event extension properties on the events struct + using (writer.Block($"extension({safeName}_MockEvents events)")) + { + bool first = true; + foreach (var evt in model.Events) + { + if (!first) writer.AppendLine(); + first = false; + + writer.AppendLine($"public global::TUnit.Mocks.EventSubscriptionAccessor {evt.Name}"); + writer.AppendLine($" => new(events.Engine, \"{evt.Name}\");"); + } + } + } + } + + return writer.ToString(); + } +} diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs index 973cee9a27..632f42ef58 100644 --- a/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs +++ b/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs @@ -10,6 +10,7 @@ public static string Build(MockTypeModel model) { var writer = new CodeWriter(); var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); + var hasEvents = model.Events.Length > 0; writer.AppendLine("// "); writer.AppendLine("#nullable enable"); @@ -55,27 +56,29 @@ public static string Build(MockTypeModel model) // Generate typed wrapper structs for qualifying methods foreach (var method in model.Methods) { - if (!ShouldGenerateTypedWrapper(method)) continue; + if (!ShouldGenerateTypedWrapper(method, hasEvents)) continue; writer.AppendLine(); - GenerateTypedWrapperStruct(writer, method, safeName); + GenerateTypedWrapperStruct(writer, method, safeName, model.Events); } } return writer.ToString(); } - private static bool ShouldGenerateTypedWrapper(MockMemberModel method) + private static bool ShouldGenerateTypedWrapper(MockMemberModel method, bool hasEvents) { if (method.IsGenericMethod) return false; var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); - return nonOutParams.Count >= 1 && nonOutParams.Count <= MaxTypedParams; + if (nonOutParams.Count == 0) return hasEvents; + return nonOutParams.Count <= MaxTypedParams; } private static string GetWrapperName(string safeName, MockMemberModel method) => $"{safeName}_{method.Name}_M{method.MemberId}_TypedSetup"; - private static void GenerateTypedWrapperStruct(CodeWriter writer, MockMemberModel method, string safeName) + private static void GenerateTypedWrapperStruct(CodeWriter writer, MockMemberModel method, string safeName, + EquatableArray events) { var setupReturnType = method.IsAsync && !method.IsVoid ? method.UnwrappedReturnType @@ -86,152 +89,263 @@ private static void GenerateTypedWrapperStruct(CodeWriter writer, MockMemberMode if (method.IsVoid) { - GenerateVoidTypedWrapper(writer, wrapperName, nonOutParams); + GenerateVoidTypedWrapper(writer, wrapperName, nonOutParams, events); } else { - GenerateReturnTypedWrapper(writer, wrapperName, nonOutParams, setupReturnType); + GenerateReturnTypedWrapper(writer, wrapperName, nonOutParams, setupReturnType, events); } } private static void GenerateReturnTypedWrapper(CodeWriter writer, string wrapperName, - List nonOutParams, string returnType) + List nonOutParams, string returnType, EquatableArray events) { var chainType = $"global::TUnit.Mocks.Setup.ISetupChain<{returnType}>"; var setupInterface = $"global::TUnit.Mocks.Setup.IMethodSetup<{returnType}>"; var builderType = $"global::TUnit.Mocks.Setup.MethodSetupBuilder<{returnType}>"; + // Only implement both interfaces when there are events — the dual-interface pattern + // preserves the concrete wrapper type through the chain so RaisesX() stays accessible. + var interfaces = events.Length > 0 ? $" : {setupInterface}, {chainType}" : ""; + writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); - using (writer.Block($"public readonly struct {wrapperName} : {setupInterface}")) + using (writer.Block($"public readonly struct {wrapperName}{interfaces}")) { writer.AppendLine($"private readonly {builderType} _inner;"); writer.AppendLine(); writer.AppendLine($"internal {wrapperName}({builderType} inner) => _inner = inner;"); + + if (events.Length > 0) + { + writer.AppendLine(); + + // Explicit IMethodSetup implementations + writer.AppendLine($"{chainType} {setupInterface}.Returns({returnType} value) => _inner.Returns(value);"); + writer.AppendLine($"{chainType} {setupInterface}.Returns(global::System.Func<{returnType}> factory) => _inner.Returns(factory);"); + writer.AppendLine($"{chainType} {setupInterface}.ReturnsSequentially(params {returnType}[] values) => _inner.ReturnsSequentially(values);"); + writer.AppendLine($"{chainType} {setupInterface}.Throws() => _inner.Throws();"); + writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Exception exception) => _inner.Throws(exception);"); + writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"{chainType} {setupInterface}.Returns(global::System.Func factory) => _inner.Returns(factory);"); + writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); + writer.AppendLine($"{chainType} {setupInterface}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); + writer.AppendLine($"{chainType} {setupInterface}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"{chainType} {setupInterface}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); + writer.AppendLine(); + + // Explicit ISetupChain implementations + writer.AppendLine($"{setupInterface} {chainType}.Then() {{ _inner.Then(); return this; }}"); + writer.AppendLine($"{chainType} {chainType}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); + writer.AppendLine($"{chainType} {chainType}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"{chainType} {chainType}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); + } + writer.AppendLine(); - // Forward all IMethodSetup members + // Public self-returning methods (preserve wrapper type through fluent chain) writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Returns({returnType} value) => _inner.Returns(value);"); + writer.AppendLine($"public {wrapperName} Returns({returnType} value) {{ _inner.Returns(value); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Returns(global::System.Func<{returnType}> factory) => _inner.Returns(factory);"); + writer.AppendLine($"public {wrapperName} Returns(global::System.Func<{returnType}> factory) {{ _inner.Returns(factory); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} ReturnsSequentially(params {returnType}[] values) => _inner.ReturnsSequentially(values);"); + writer.AppendLine($"public {wrapperName} ReturnsSequentially(params {returnType}[] values) {{ _inner.ReturnsSequentially(values); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws() where TException : global::System.Exception, new() => _inner.Throws();"); + writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ _inner.Throws(); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws(global::System.Exception exception) => _inner.Throws(exception);"); + writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ _inner.Throws(exception); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Returns(global::System.Func factory) => _inner.Returns(factory);"); + writer.AppendLine($"public {wrapperName} Returns(global::System.Func factory) {{ _inner.Returns(factory); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); + writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ _inner.Throws(exceptionFactory); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Raises(string eventName, object? args = null) => _inner.Raises(eventName, args);"); + writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ _inner.Raises(eventName, args); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ _inner.SetsOutParameter(paramIndex, value); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - writer.AppendLine(); + writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ _inner.TransitionsTo(stateName); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Then() {{ _inner.Then(); return this; }}"); - // Typed overloads - GenerateTypedReturnsOverload(writer, nonOutParams, returnType, chainType); - writer.AppendLine(); - GenerateTypedCallbackOverload(writer, nonOutParams, chainType, isVoid: false); - writer.AppendLine(); - GenerateTypedThrowsOverload(writer, nonOutParams, chainType, isVoid: false); + // Typed parameter overloads (only for methods with typed params) + if (nonOutParams.Count >= 1) + { + writer.AppendLine(); + GenerateTypedReturnsOverload(writer, nonOutParams, returnType, wrapperName); + writer.AppendLine(); + GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); + writer.AppendLine(); + GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); + } + + // Typed event raises + if (events.Length > 0) + { + writer.AppendLine(); + GenerateTypedEventRaises(writer, events, wrapperName); + } } } private static void GenerateVoidTypedWrapper(CodeWriter writer, string wrapperName, - List nonOutParams) + List nonOutParams, EquatableArray events) { var chainType = "global::TUnit.Mocks.Setup.IVoidSetupChain"; var setupInterface = "global::TUnit.Mocks.Setup.IVoidMethodSetup"; var builderType = "global::TUnit.Mocks.Setup.VoidMethodSetupBuilder"; + // Only implement both interfaces when there are events — the dual-interface pattern + // preserves the concrete wrapper type through the chain so RaisesX() stays accessible. + var interfaces = events.Length > 0 ? $" : {setupInterface}, {chainType}" : ""; + writer.AppendLine($"[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); - using (writer.Block($"public readonly struct {wrapperName} : {setupInterface}")) + using (writer.Block($"public readonly struct {wrapperName}{interfaces}")) { writer.AppendLine($"private readonly {builderType} _inner;"); writer.AppendLine(); writer.AppendLine($"internal {wrapperName}({builderType} inner) => _inner = inner;"); + + if (events.Length > 0) + { + writer.AppendLine(); + + // Explicit IVoidMethodSetup implementations + writer.AppendLine($"{chainType} {setupInterface}.Throws() => _inner.Throws();"); + writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Exception exception) => _inner.Throws(exception);"); + writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); + writer.AppendLine($"{chainType} {setupInterface}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); + writer.AppendLine($"{chainType} {setupInterface}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"{chainType} {setupInterface}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); + writer.AppendLine(); + + // Explicit IVoidSetupChain implementations + writer.AppendLine($"{setupInterface} {chainType}.Then() {{ _inner.Then(); return this; }}"); + writer.AppendLine($"{chainType} {chainType}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); + writer.AppendLine($"{chainType} {chainType}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"{chainType} {chainType}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); + } + writer.AppendLine(); - // Forward all IVoidMethodSetup members + // Public self-returning methods (preserve wrapper type through fluent chain) writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws() where TException : global::System.Exception, new() => _inner.Throws();"); + writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ _inner.Throws(); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws(global::System.Exception exception) => _inner.Throws(exception);"); + writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ _inner.Throws(exception); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Callback(global::System.Action callback) => _inner.Callback(callback);"); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); + writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ _inner.Throws(exceptionFactory); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} Raises(string eventName, object? args = null) => _inner.Raises(eventName, args);"); + writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ _inner.Raises(eventName, args); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); + writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ _inner.SetsOutParameter(paramIndex, value); return this; }}"); writer.AppendLine($"/// "); - writer.AppendLine($"public {chainType} TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - writer.AppendLine(); + writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ _inner.TransitionsTo(stateName); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Then() {{ _inner.Then(); return this; }}"); - // Typed overloads (no Returns for void) - GenerateTypedCallbackOverload(writer, nonOutParams, chainType, isVoid: true); - writer.AppendLine(); - GenerateTypedThrowsOverload(writer, nonOutParams, chainType, isVoid: true); + // Typed parameter overloads (only for methods with typed params) + if (nonOutParams.Count >= 1) + { + writer.AppendLine(); + GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); + writer.AppendLine(); + GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); + } + + // Typed event raises + if (events.Length > 0) + { + writer.AppendLine(); + GenerateTypedEventRaises(writer, events, wrapperName); + } } } private static void GenerateTypedReturnsOverload(CodeWriter writer, List nonOutParams, - string returnType, string chainType) + string returnType, string wrapperName) { var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); var funcType = $"global::System.Func<{typeList}, {returnType}>"; var castArgs = BuildCastArgs(nonOutParams); writer.AppendLine("/// Configure a typed computed return value using the actual method parameters."); - using (writer.Block($"public {chainType} Returns({funcType} factory)")) + using (writer.Block($"public {wrapperName} Returns({funcType} factory)")) { - writer.AppendLine($"return _inner.Returns(args => factory({castArgs}));"); + writer.AppendLine($"_inner.Returns(args => factory({castArgs}));"); + writer.AppendLine("return this;"); } } private static void GenerateTypedCallbackOverload(CodeWriter writer, List nonOutParams, - string chainType, bool isVoid) + string wrapperName) { var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); var actionType = $"global::System.Action<{typeList}>"; var castArgs = BuildCastArgs(nonOutParams); writer.AppendLine("/// Execute a typed callback using the actual method parameters."); - using (writer.Block($"public {chainType} Callback({actionType} callback)")) + using (writer.Block($"public {wrapperName} Callback({actionType} callback)")) { - if (isVoid) - { - writer.AppendLine($"return _inner.Callback(args => callback({castArgs}));"); - } - else - { - writer.AppendLine($"return _inner.Callback(args => callback({castArgs}));"); - } + writer.AppendLine($"_inner.Callback(args => callback({castArgs}));"); + writer.AppendLine("return this;"); } } private static void GenerateTypedThrowsOverload(CodeWriter writer, List nonOutParams, - string chainType, bool isVoid) + string wrapperName) { var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); var funcType = $"global::System.Func<{typeList}, global::System.Exception>"; var castArgs = BuildCastArgs(nonOutParams); writer.AppendLine("/// Configure a typed computed exception using the actual method parameters."); - using (writer.Block($"public {chainType} Throws({funcType} exceptionFactory)")) + using (writer.Block($"public {wrapperName} Throws({funcType} exceptionFactory)")) { - writer.AppendLine($"return _inner.Throws(args => exceptionFactory({castArgs}));"); + writer.AppendLine($"_inner.Throws(args => exceptionFactory({castArgs}));"); + writer.AppendLine("return this;"); + } + } + + private static void GenerateTypedEventRaises(CodeWriter writer, EquatableArray events, + string wrapperName) + { + bool first = true; + foreach (var evt in events) + { + if (!first) writer.AppendLine(); + first = false; + + var paramList = evt.RaiseParameterList.Length == 0 + ? "" + : string.Join(", ", evt.RaiseParameterList.Select(p => $"{p.FullyQualifiedType} {p.Name}")); + + string argsExpr; + if (evt.RaiseParameterList.Length == 0) + { + argsExpr = ""; + } + else if (evt.RaiseParameterList.Length == 1) + { + argsExpr = $", (object?){evt.RaiseParameterList[0].Name}"; + } + else + { + var argNames = string.Join(", ", evt.RaiseParameterList.Select(p => p.Name)); + argsExpr = $", (object?)new object?[] {{ {argNames} }}"; + } + + writer.AppendLine($"/// Auto-raise the {evt.Name} event when this method is called."); + writer.AppendLine($"public {wrapperName} Raises{evt.Name}({paramList}) {{ _inner.Raises(\"{evt.Name}\"{argsExpr}); return this; }}"); } } @@ -249,7 +363,8 @@ private static void GenerateSetupMethod(CodeWriter writer, MockMemberModel metho ? method.UnwrappedReturnType : method.ReturnType; - var useTypedWrapper = ShouldGenerateTypedWrapper(method); + var hasEvents = model.Events.Length > 0; + var useTypedWrapper = ShouldGenerateTypedWrapper(method, hasEvents); string returnType; if (useTypedWrapper) diff --git a/TUnit.Mocks.SourceGenerator/MockGenerator.cs b/TUnit.Mocks.SourceGenerator/MockGenerator.cs index 9366796fdd..dbb54d9cf5 100644 --- a/TUnit.Mocks.SourceGenerator/MockGenerator.cs +++ b/TUnit.Mocks.SourceGenerator/MockGenerator.cs @@ -70,6 +70,9 @@ private static void GenerateSingleTypeMock(SourceProductionContext spc, MockType { var raiseSource = MockRaiseBuilder.Build(model); spc.AddSource($"{fileName}_MockRaise.g.cs", raiseSource); + + var eventsSource = MockEventsBuilder.Build(model); + spc.AddSource($"{fileName}_MockEvents.g.cs", eventsSource); } // Generate factory @@ -116,6 +119,9 @@ private static void GenerateWrapMock(SourceProductionContext spc, MockTypeModel { var raiseSource = MockRaiseBuilder.Build(model); spc.AddSource($"{fileName}_MockRaise.g.cs", raiseSource); + + var eventsSource = MockEventsBuilder.Build(model); + spc.AddSource($"{fileName}_MockEvents.g.cs", eventsSource); } // Generate wrap factory diff --git a/TUnit.Mocks.Tests/AutoRaiseEventTests.cs b/TUnit.Mocks.Tests/AutoRaiseEventTests.cs index b3a5a43d74..f0049421b6 100644 --- a/TUnit.Mocks.Tests/AutoRaiseEventTests.cs +++ b/TUnit.Mocks.Tests/AutoRaiseEventTests.cs @@ -7,6 +7,14 @@ public interface IProcessService void Execute(string command); } +public interface IMultiEventService +{ + event Action OnMultiParam; + event Action OnSimple; + void Trigger(); + string Query(); +} + public class AutoRaiseEventTests { [Test] @@ -19,7 +27,7 @@ public async Task Raises_Event_When_Method_Returns_Value() mock.Setup.Process(Arg.Any()) .Returns(true) - .Raises("StatusChanged", "completed"); + .RaisesStatusChanged("completed"); mock.Object.Process(42); @@ -35,7 +43,7 @@ public async Task Raises_Event_When_Void_Method_Called() mock.Object.StatusChanged += (sender, status) => receivedStatus = status; mock.Setup.Execute(Arg.Any()) - .Raises("StatusChanged", "executed"); + .RaisesStatusChanged("executed"); mock.Object.Execute("run"); @@ -52,8 +60,8 @@ public async Task Multiple_Raises_Fire_In_Order() mock.Setup.Process(Arg.Any()) .Returns(true) - .Raises("StatusChanged", "first") - .Raises("StatusChanged", "second"); + .RaisesStatusChanged("first") + .RaisesStatusChanged("second"); mock.Object.Process(1); @@ -69,7 +77,7 @@ public async Task Raises_With_No_Subscribers_Does_Not_Throw() mock.Setup.Process(Arg.Any()) .Returns(true) - .Raises("StatusChanged", "ignored"); + .RaisesStatusChanged("ignored"); // No subscriber — should not throw var result = mock.Object.Process(1); @@ -87,7 +95,7 @@ public async Task Raises_On_Each_Call() mock.Setup.Process(Arg.Any()) .Returns(true) - .Raises("StatusChanged", "ping"); + .RaisesStatusChanged("ping"); mock.Object.Process(1); mock.Object.Process(2); @@ -95,4 +103,60 @@ public async Task Raises_On_Each_Call() await Assert.That(callCount).IsEqualTo(3); } + + [Test] + public async Task Raises_Event_From_Zero_Param_Void_Method() + { + var mock = Mock.Of(); + var wasCalled = false; + + mock.Object.OnSimple += () => wasCalled = true; + + mock.Setup.Trigger() + .RaisesOnSimple(); + + mock.Object.Trigger(); + + await Assert.That(wasCalled).IsTrue(); + } + + [Test] + public async Task Raises_Event_From_Zero_Param_Return_Method() + { + var mock = Mock.Of(); + var wasCalled = false; + + mock.Object.OnSimple += () => wasCalled = true; + + mock.Setup.Query() + .Returns("result") + .RaisesOnSimple(); + + var result = mock.Object.Query(); + + await Assert.That(wasCalled).IsTrue(); + await Assert.That(result).IsEqualTo("result"); + } + + [Test] + public async Task Raises_Multi_Param_Event_Unpacks_Arguments() + { + var mock = Mock.Of(); + string? receivedName = null; + int receivedCount = 0; + + mock.Object.OnMultiParam += (name, count) => + { + receivedName = name; + receivedCount = count; + }; + + mock.Setup.Trigger() + .RaisesOnMultiParam("hello", 42); + + mock.Object.Trigger(); + + await Assert.That(receivedName).IsEqualTo("hello"); + await Assert.That(receivedCount).IsEqualTo(42); + } } diff --git a/TUnit.Mocks.Tests/EventSubscriptionSetupTests.cs b/TUnit.Mocks.Tests/EventSubscriptionSetupTests.cs index a1140eb5c4..3f2c6835d6 100644 --- a/TUnit.Mocks.Tests/EventSubscriptionSetupTests.cs +++ b/TUnit.Mocks.Tests/EventSubscriptionSetupTests.cs @@ -13,7 +13,7 @@ public async Task OnSubscribe_Callback_Fires_When_Handler_Subscribes() var mock = Mock.Of(); var callbackFired = false; - mock.OnSubscribe("DataReady", () => callbackFired = true); + mock.Events.DataReady.OnSubscribe(() => callbackFired = true); mock.Object.DataReady += (sender, args) => { }; @@ -26,7 +26,7 @@ public async Task OnUnsubscribe_Callback_Fires_When_Handler_Unsubscribes() var mock = Mock.Of(); var callbackFired = false; - mock.OnUnsubscribe("DataReady", () => callbackFired = true); + mock.Events.DataReady.OnUnsubscribe(() => callbackFired = true); EventHandler handler = (sender, args) => { }; mock.Object.DataReady += handler; @@ -41,7 +41,7 @@ public async Task Multiple_Subscriptions_Fire_Callback_Each_Time() var mock = Mock.Of(); var callCount = 0; - mock.OnSubscribe("DataReady", () => callCount++); + mock.Events.DataReady.OnSubscribe(() => callCount++); mock.Object.DataReady += (sender, args) => { }; mock.Object.DataReady += (sender, args) => { }; @@ -58,7 +58,7 @@ public async Task No_Callback_Fires_When_None_Configured() // Subscribe without configuring any callback — should not throw mock.Object.DataReady += (sender, args) => { }; - await Assert.That(mock.WasEventSubscribed("DataReady")).IsTrue(); + await Assert.That(mock.Events.DataReady.WasSubscribed).IsTrue(); } [Test] @@ -68,8 +68,8 @@ public async Task Subscribe_And_Unsubscribe_Callbacks_Work_Independently() var subscribeCount = 0; var unsubscribeCount = 0; - mock.OnSubscribe("DataReady", () => subscribeCount++); - mock.OnUnsubscribe("DataReady", () => unsubscribeCount++); + mock.Events.DataReady.OnSubscribe(() => subscribeCount++); + mock.Events.DataReady.OnUnsubscribe(() => unsubscribeCount++); EventHandler handler = (sender, args) => { }; mock.Object.DataReady += handler; @@ -86,7 +86,7 @@ public async Task Reset_Clears_Subscription_Callbacks() var mock = Mock.Of(); var callbackFired = false; - mock.OnSubscribe("DataReady", () => callbackFired = true); + mock.Events.DataReady.OnSubscribe(() => callbackFired = true); mock.Reset(); mock.Object.DataReady += (sender, args) => { }; diff --git a/TUnit.Mocks.Tests/EventSubscriptionVerifyTests.cs b/TUnit.Mocks.Tests/EventSubscriptionVerifyTests.cs index 93b4bfc55e..3ff007ccb7 100644 --- a/TUnit.Mocks.Tests/EventSubscriptionVerifyTests.cs +++ b/TUnit.Mocks.Tests/EventSubscriptionVerifyTests.cs @@ -15,7 +15,7 @@ public async Task WasEventSubscribed_Returns_True_After_Subscribe() mock.Object.OnStringAction += _ => { }; // Assert - await Assert.That(mock.WasEventSubscribed("OnStringAction")).IsTrue(); + await Assert.That(mock.Events.OnStringAction.WasSubscribed).IsTrue(); } [Test] @@ -25,7 +25,7 @@ public async Task WasEventSubscribed_Returns_False_When_No_Subscription() var mock = Mock.Of(); // Assert - await Assert.That(mock.WasEventSubscribed("OnStringAction")).IsFalse(); + await Assert.That(mock.Events.OnStringAction.WasSubscribed).IsFalse(); } [Test] @@ -39,7 +39,7 @@ public async Task GetEventSubscriberCount_Tracks_Subscriptions() mock.Object.OnStringAction += _ => { }; // Assert - await Assert.That(mock.GetEventSubscriberCount("OnStringAction")).IsEqualTo(2); + await Assert.That(mock.Events.OnStringAction.SubscriberCount).IsEqualTo(2); } [Test] @@ -55,7 +55,7 @@ public async Task GetEventSubscriberCount_Decrements_On_Unsubscribe() mock.Object.OnStringAction -= handler; // Assert — 2 subscribes, 1 unsubscribe = 1 remaining - await Assert.That(mock.GetEventSubscriberCount("OnStringAction")).IsEqualTo(1); + await Assert.That(mock.Events.OnStringAction.SubscriberCount).IsEqualTo(1); } [Test] @@ -70,9 +70,9 @@ public async Task Different_Events_Tracked_Independently() mock.Object.OnSimpleAction += () => { }; // Assert - await Assert.That(mock.GetEventSubscriberCount("OnStringAction")).IsEqualTo(1); - await Assert.That(mock.GetEventSubscriberCount("OnSimpleAction")).IsEqualTo(2); - await Assert.That(mock.WasEventSubscribed("OnMultiParamAction")).IsFalse(); + await Assert.That(mock.Events.OnStringAction.SubscriberCount).IsEqualTo(1); + await Assert.That(mock.Events.OnSimpleAction.SubscriberCount).IsEqualTo(2); + await Assert.That(mock.Events.OnMultiParamAction.WasSubscribed).IsFalse(); } [Test] @@ -86,7 +86,7 @@ public async Task Reset_Clears_Subscription_History() mock.Reset(); // Assert - await Assert.That(mock.WasEventSubscribed("OnStringAction")).IsFalse(); - await Assert.That(mock.GetEventSubscriberCount("OnStringAction")).IsEqualTo(0); + await Assert.That(mock.Events.OnStringAction.WasSubscribed).IsFalse(); + await Assert.That(mock.Events.OnStringAction.SubscriberCount).IsEqualTo(0); } } diff --git a/TUnit.Mocks/EventSubscriptionAccessor.cs b/TUnit.Mocks/EventSubscriptionAccessor.cs new file mode 100644 index 0000000000..9c8689f98c --- /dev/null +++ b/TUnit.Mocks/EventSubscriptionAccessor.cs @@ -0,0 +1,34 @@ +using System.ComponentModel; + +namespace TUnit.Mocks; + +/// +/// Lightweight accessor for event subscription queries and callbacks. +/// Returns from generated extension properties like mock.Events.StatusChanged. +/// +[EditorBrowsable(EditorBrowsableState.Never)] +public readonly struct EventSubscriptionAccessor +{ + private readonly IMockEngineAccess _engine; + private readonly string _eventName; + + /// Creates a new event subscription accessor. + [EditorBrowsable(EditorBrowsableState.Never)] + public EventSubscriptionAccessor(IMockEngineAccess engine, string eventName) + { + _engine = engine; + _eventName = eventName; + } + + /// Returns true if the event was ever subscribed to. + public bool WasSubscribed => _engine.WasEventSubscribed(_eventName); + + /// Gets the current number of subscribers for this event. + public int SubscriberCount => _engine.GetEventSubscriberCount(_eventName); + + /// Registers a callback that fires when a handler subscribes to this event. + public void OnSubscribe(Action callback) => _engine.OnSubscribe(_eventName, callback); + + /// Registers a callback that fires when a handler unsubscribes from this event. + public void OnUnsubscribe(Action callback) => _engine.OnUnsubscribe(_eventName, callback); +} diff --git a/TUnit.Mocks/IMockEngineAccess.cs b/TUnit.Mocks/IMockEngineAccess.cs index 48987aa758..9ceb9065af 100644 --- a/TUnit.Mocks/IMockEngineAccess.cs +++ b/TUnit.Mocks/IMockEngineAccess.cs @@ -17,4 +17,16 @@ public interface IMockEngineAccess /// Creates a call verification builder for the specified member. ICallVerification CreateVerification(int memberId, string memberName, IArgumentMatcher[] matchers); + + /// Registers a callback that fires when a handler subscribes to the named event. + void OnSubscribe(string eventName, Action callback); + + /// Registers a callback that fires when a handler unsubscribes from the named event. + void OnUnsubscribe(string eventName, Action callback); + + /// Gets the current subscriber count for the named event. + int GetEventSubscriberCount(string eventName); + + /// Returns true if the named event was ever subscribed to. + bool WasEventSubscribed(string eventName); } diff --git a/TUnit.Mocks/MockOfT.cs b/TUnit.Mocks/MockOfT.cs index a5db2d8d48..5bc8783360 100644 --- a/TUnit.Mocks/MockOfT.cs +++ b/TUnit.Mocks/MockOfT.cs @@ -87,26 +87,6 @@ public void SetupAllProperties() /// Clears all setups and call history. public void Reset() => Engine.Reset(); - /// - /// Registers a callback that fires when a handler subscribes to the named event. - /// - public void OnSubscribe(string eventName, Action callback) => Engine.OnSubscribe(eventName, callback); - - /// - /// Registers a callback that fires when a handler unsubscribes from the named event. - /// - public void OnUnsubscribe(string eventName, Action callback) => Engine.OnUnsubscribe(eventName, callback); - - /// - /// Gets the current number of subscribers for the named event. - /// - public int GetEventSubscriberCount(string eventName) => Engine.GetEventSubscriberCount(eventName); - - /// - /// Returns true if the named event was ever subscribed to. - /// - public bool WasEventSubscribed(string eventName) => Engine.WasEventSubscribed(eventName); - /// /// Verifies all registered setups were invoked at least once. /// Throws listing uninvoked setups. diff --git a/docs/docs/test-authoring/mocking/advanced.md b/docs/docs/test-authoring/mocking/advanced.md index 408e17d2ef..5e1ec4c1b1 100644 --- a/docs/docs/test-authoring/mocking/advanced.md +++ b/docs/docs/test-authoring/mocking/advanced.md @@ -30,31 +30,35 @@ mock.Raise.OnMessage("Hello!"); ### Auto-Raise on Method Call -Trigger an event automatically when a method is called using `.Raises()` on a setup chain: +Trigger an event automatically when a method is called using the typed `.Raises{EventName}()` method on a setup chain: ```csharp mock.Setup.SendMessage(Arg.Any()) - .Raises("OnMessage", "echo"); + .RaisesOnMessage("echo"); mock.Object.SendMessage("test"); // OnMessage event fires with "echo" ``` -### Event Subscription Callbacks +The typed raise methods are generated per-event with correct parameter types, giving you IntelliSense and compile-time safety. The string-based `.Raises(eventName, args)` overload is still available for dynamic scenarios. -React when handlers are added or removed from events: +### Event Subscription Tracking + +Query and react to event subscriptions through the strongly-typed `Events` surface: ```csharp -var subscribed = false; -mock.OnSubscribe("OnMessage", () => subscribed = true); -mock.OnUnsubscribe("OnMessage", () => subscribed = false); +var mock = Mock.Of(); + +// Register callbacks for subscribe/unsubscribe +mock.Events.OnMessage.OnSubscribe(() => Console.WriteLine("subscribed")); +mock.Events.OnMessage.OnUnsubscribe(() => Console.WriteLine("unsubscribed")); mock.Object.OnMessage += (s, e) => { }; -// subscribed == true +// prints "subscribed" // Query subscriber info -var count = mock.GetEventSubscriberCount("OnMessage"); -var wasSubscribed = mock.WasEventSubscribed("OnMessage"); +var wasSubscribed = mock.Events.OnMessage.WasSubscribed; // true +var count = mock.Events.OnMessage.SubscriberCount; // 1 ``` ## State Machine Mocking diff --git a/docs/docs/test-authoring/mocking/setup.md b/docs/docs/test-authoring/mocking/setup.md index fb1fd55989..29007d0055 100644 --- a/docs/docs/test-authoring/mocking/setup.md +++ b/docs/docs/test-authoring/mocking/setup.md @@ -215,8 +215,10 @@ Setup methods return chain objects that support additional behaviors: ```csharp mock.Setup.Process(Arg.Any()) .Returns(true) - .Raises("ProcessCompleted", EventArgs.Empty) // auto-raise event - .TransitionsTo("processed"); // state machine transition + .RaisesProcessCompleted(EventArgs.Empty) // strongly-typed auto-raise event + .TransitionsTo("processed"); // state machine transition ``` +The typed `.Raises{EventName}()` methods provide IntelliSense and compile-time safety for event parameters. The string-based `.Raises(eventName, args)` overload is also available. + See [Advanced Features](advanced) for details on events and state machines.