Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions TUnit.Mocks.SourceGenerator.Tests/MockGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,174 @@ void M()
return VerifyGeneratorOutput(source);
}

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

namespace Sandbox
{
public enum SomeEnum
{
Value1,
Value2
}

public interface IFoo<T>
{
T Value { get; }
}

public class TestUsage
{
void M()
{
var mock = IFoo<SomeEnum>.Mock();
}
}
}
""";

return VerifyGeneratorOutput(source);
}

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

namespace Sandbox
{
public class Bar
{
public string Name { get; set; } = "";
}

public interface IFoo<T>
{
T Value { get; }
void Process(T item);
}

public class TestUsage
{
void M()
{
var mock = IFoo<Bar>.Mock();
}
}
}
""";

return VerifyGeneratorOutput(source);
}

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

namespace Outer.Inner
{
public class Config
{
public int Timeout { get; set; }
}
}

namespace Sandbox
{
public interface IService<T>
{
T GetConfig();
void Apply(T config);
}

public class TestUsage
{
void M()
{
var mock = IService<Outer.Inner.Config>.Mock();
}
}
}
""";

return VerifyGeneratorOutput(source);
}

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

namespace Sandbox
{
public class Entity
{
public int Id { get; set; }
}

public enum Status
{
Active,
Inactive
}

public interface IMapper<TIn, TOut>
{
TOut Map(TIn input);
}

public class TestUsage
{
void M()
{
var mock = IMapper<Entity, Status>.Mock();
}
}
}
""";

return VerifyGeneratorOutput(source);
}

[Test]
public Task Generic_Interface_With_Nested_Generic_Type_Argument()
{
var source = """
using System.Collections.Generic;
using TUnit.Mocks;

namespace Sandbox
{
public class Item
{
public string Name { get; set; } = "";
}

public interface IProvider<T>
{
T Get();
}

public class TestUsage
{
void M()
{
var mock = IProvider<List<Item>>.Mock();
}
}
}
""";

return VerifyGeneratorOutput(source);
}

[Test]
public Task Interface_With_Unconstrained_Nullable_Generic()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated.Sandbox
{
public sealed class IFoo_Bar_Mock : global::TUnit.Mocks.Mock<global::Sandbox.IFoo<global::Sandbox.Bar>>, global::Sandbox.IFoo<global::Sandbox.Bar>
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal IFoo_Bar_Mock(global::Sandbox.IFoo<global::Sandbox.Bar> mockObject, global::TUnit.Mocks.MockEngine<global::Sandbox.IFoo<global::Sandbox.Bar>> engine)
: base(mockObject, engine) { }

void global::Sandbox.IFoo<global::Sandbox.Bar>.Process(global::Sandbox.Bar item)
{
Object.Process(item);
}

global::Sandbox.Bar global::Sandbox.IFoo<global::Sandbox.Bar>.Value { get => Object.Value; }
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated.Sandbox
{
file sealed class IFoo_Bar_MockImpl : global::Sandbox.IFoo<global::Sandbox.Bar>, global::TUnit.Mocks.IRaisable, global::TUnit.Mocks.IMockObject
{
private readonly global::TUnit.Mocks.MockEngine<global::Sandbox.IFoo<global::Sandbox.Bar>> _engine;

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

internal IFoo_Bar_MockImpl(global::TUnit.Mocks.MockEngine<global::Sandbox.IFoo<global::Sandbox.Bar>> engine)
{
_engine = engine;
}

public void Process(global::Sandbox.Bar item)
{
_engine.HandleCall<global::Sandbox.Bar>(1, "Process", item);
}

public global::Sandbox.Bar Value
{
get => _engine.HandleCallWithReturn<global::Sandbox.Bar>(0, "get_Value", global::System.Array.Empty<object?>(), default!);
}

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

file static class IFoo_Bar_MockFactory
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
internal static void Register()
{
global::TUnit.Mocks.MockRegistry.RegisterFactory<global::Sandbox.IFoo<global::Sandbox.Bar>>(Create);
}

internal static global::TUnit.Mocks.Mock<global::Sandbox.IFoo<global::Sandbox.Bar>> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
if (constructorArgs.Length > 0) throw new global::System.ArgumentException($"Interface mock 'global::Sandbox.IFoo<global::Sandbox.Bar>' does not support constructor arguments, but {constructorArgs.Length} were provided.");
var engine = new global::TUnit.Mocks.MockEngine<global::Sandbox.IFoo<global::Sandbox.Bar>>(behavior);
var impl = new IFoo_Bar_MockImpl(engine);
engine.Raisable = impl;
var mock = new IFoo_Bar_Mock(impl, engine);
return mock;
}
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
public static class Sandbox_IFoo_Sandbox_Bar__MockMemberExtensions
{
public static Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Process(this global::TUnit.Mocks.Mock<global::Sandbox.IFoo<global::Sandbox.Bar>> mock, global::TUnit.Mocks.Arguments.Arg<global::Sandbox.Bar> item)
{
var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { item.Matcher };
return new Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall(global::TUnit.Mocks.MockRegistry.GetEngine(mock), 1, "Process", matchers);
}

public static Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Process(this global::TUnit.Mocks.Mock<global::Sandbox.IFoo<global::Sandbox.Bar>> mock, global::System.Func<global::Sandbox.Bar, bool> item)
{
global::TUnit.Mocks.Arguments.Arg<global::Sandbox.Bar> __fa_item = item;
var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { __fa_item.Matcher };
return new Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall(global::TUnit.Mocks.MockRegistry.GetEngine(mock), 1, "Process", matchers);
}

extension(global::TUnit.Mocks.Mock<global::Sandbox.IFoo<global::Sandbox.Bar>> mock)
{
public global::TUnit.Mocks.PropertyMockCall<global::Sandbox.Bar> Value
=> new(global::TUnit.Mocks.MockRegistry.GetEngine(mock), 0, 0, "Value", true, false);
}
}

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public sealed class Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall : global::TUnit.Mocks.Verification.ICallVerification
{
private readonly global::TUnit.Mocks.IMockEngineAccess _engine;
private readonly int _memberId;
private readonly string _memberName;
private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers;
private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder? _builder;
private bool _builderInitialized;
private object? _builderLock;

internal Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers)
{
_engine = engine;
_memberId = memberId;
_memberName = memberName;
_matchers = matchers;
_ = EnsureSetup();
}

private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() =>
global::System.Threading.LazyInitializer.EnsureInitialized(ref _builder, ref _builderInitialized, ref _builderLock, () =>
{
var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName);
_engine.AddSetup(setup);
return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup);
})!;

/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Returns() { EnsureSetup().Returns(); return this; }
/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Throws<TException>() where TException : global::System.Exception, new() { EnsureSetup().Throws<TException>(); return this; }
/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; }
/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; }
/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; }
/// <inheritdoc />
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Then() { EnsureSetup().Then(); return this; }

/// <summary>Execute a typed callback using the actual method parameters.</summary>
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Callback(global::System.Action<global::Sandbox.Bar> callback)
{
EnsureSetup().Callback(args => callback((global::Sandbox.Bar)args[0]!));
return this;
}

/// <summary>Configure a typed computed exception using the actual method parameters.</summary>
public Sandbox_IFoo_Sandbox_Bar__Process_M1_MockCall Throws(global::System.Func<global::Sandbox.Bar, global::System.Exception> exceptionFactory)
{
EnsureSetup().Throws(args => exceptionFactory((global::Sandbox.Bar)args[0]!));
return this;
}

// ICallVerification
/// <inheritdoc />
public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled();
/// <inheritdoc />
public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times);
/// <inheritdoc />
public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message);
/// <inheritdoc />
public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message);
/// <inheritdoc />
public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled();
/// <inheritdoc />
public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message);
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks
{
public static class Sandbox_IFoo_Sandbox_Bar__MockStaticExtension
{
extension(global::Sandbox.IFoo<global::Sandbox.Bar>)
{
public static global::TUnit.Mocks.Generated.Sandbox.IFoo_Bar_Mock Mock(global::TUnit.Mocks.MockBehavior behavior = global::TUnit.Mocks.MockBehavior.Loose)
{
return (global::TUnit.Mocks.Generated.Sandbox.IFoo_Bar_Mock)global::TUnit.Mocks.Mock.Of<global::Sandbox.IFoo<global::Sandbox.Bar>>(behavior);
}
}
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated;
Loading
Loading