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
6 changes: 6 additions & 0 deletions GeneratorTests/Moq.AutoMocker.Generator.Example/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ public Controller(ILogger<Controller> logger)
_ = logger ?? throw new ArgumentNullException(nameof(logger));
}

public Controller(ILogger<Controller> logger, CancellationToken token)
{
_ = logger ?? throw new ArgumentNullException(nameof(logger));
_ = token;
}

public string Name { get; } = "";
}
39 changes: 39 additions & 0 deletions Moq.AutoMock.Tests/ResolvesCancellationToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Moq.AutoMock.Tests;

[TestClass]
public class ResolvesCancellationToken
{
[TestMethod]
public void Resolves_cancellation_token_none_when_nothing_has_been_registered()
{
AutoMocker mocker = new();

CancellationToken token = mocker.Get<CancellationToken>();

Assert.AreEqual(CancellationToken.None, token);
}

[TestMethod]
public void Resolves_cancellation_token_with_cached_instance()
{
using CancellationTokenSource cts = new();
AutoMocker mocker = new();
mocker.Use(cts.Token);

CancellationToken token = mocker.Get<CancellationToken>();

Assert.AreEqual(cts.Token, token);
}

[TestMethod]
public void Resolves_cancellation_token_from_cached_cancellation_token_source()
{
using CancellationTokenSource cts = new();
AutoMocker mocker = new();
mocker.Use(cts);

CancellationToken token = mocker.Get<CancellationToken>();

Assert.AreEqual(cts.Token, token);
}
}
9 changes: 5 additions & 4 deletions Moq.AutoMock/AutoMocker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public AutoMocker(MockBehavior mockBehavior, DefaultValue defaultValue, DefaultV
new EnumerableResolver(),
new LazyResolver(),
new FuncResolver(),
new CancellationTokenResolver(),
new MockResolver(mockBehavior, defaultValue, defaultValueProvider, callBase),
};
}
Expand Down Expand Up @@ -536,12 +537,12 @@ public void With(Type implementationType)
/// </summary>
/// <typeparam name="TService">The class or interface to search on</typeparam>
/// <returns>The object that implements TService</returns>
public TService Get<TService>() where TService : class?
public TService Get<TService>()
{
if (Get(typeof(TService)) is TService service)
return service;

return null!;
return default!;
}

/// <summary>
Expand All @@ -551,12 +552,12 @@ public TService Get<TService>() where TService : class?
/// <typeparam name="TService">The class or interface to search on</typeparam>
/// <param name="enablePrivate">When true, non-public constructors will also be used to create mocks.</param>
/// <returns>The object that implements TService</returns>
public TService Get<TService>(bool enablePrivate) where TService : class?
public TService Get<TService>(bool enablePrivate)
{
if (Get(typeof(TService), enablePrivate) is TService service)
return service;

return null!;
return default!;
}

/// <summary>
Expand Down
29 changes: 29 additions & 0 deletions Moq.AutoMock/Resolvers/CancellationTokenResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Moq.AutoMock.Resolvers;
/// <summary>
/// A resolve that can provide a <see cref="CancellationToken"/>
/// </summary>
public class CancellationTokenResolver : IMockResolver
{
/// <inheritdoc />
public void Resolve(MockResolutionContext context)
{
if (context.RequestType == typeof(CancellationToken))
{
if (context.AutoMocker.ResolvedObjects?.TryGetValue(typeof(CancellationTokenSource), out object? ctsObject) == true &&
ctsObject is CancellationTokenSource cts)
{
context.Value = cts.Token;
}
else
{
context.Value = CancellationToken.None;
}
}
}
}
44 changes: 44 additions & 0 deletions Moq.AutoMocker.TestGenerator.Tests/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,50 @@ public void ControllerConstructor_WithNullILoggerController_ThrowsArgumentNullEx
}.RunAsync();
}

[TestMethod]
public async Task Generation_WithValueTypeParameter_DoesNotGenerateTest()
{
var code = @"
using Moq.AutoMock;
using System.Threading;

namespace TestNamespace;

[ConstructorTests(typeof(Controller))]
public partial class ControllerTests
{

}

public class Controller
{
public Controller(CancellationToken token) { }
}
";
string expected = @"namespace TestNamespace
{
partial class ControllerTests
{
partial void AutoMockerTestSetup(Moq.AutoMock.AutoMocker mocker, string testName);

}
}
";

await new VerifyCS.Test
{
TestCode = code,
TestState =
{
GeneratedSources =
{
GetSourceFile(expected, "ControllerTests.g.cs")
}
}

}.RunAsync();
}

private static (string FileName, SourceText SourceText) GetSourceFile(string content, string fileName)
{
return (Path.Combine("Moq.AutoMocker.TestGenerator", "Moq.AutoMocker.TestGenerator.UnitTestSourceGenerator", fileName), SourceText.From(content, Encoding.UTF8));
Expand Down
3 changes: 2 additions & 1 deletion Moq.AutoMocker.TestGenerator/SyntaxReceiver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

Expand Down Expand Up @@ -66,6 +66,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
int nullIndex = 0;
foreach (IParameterSymbol parameter in ctor.Parameters)
{
if (parameter.Type.IsValueType) continue;
sut.NullConstructorParameterTests.Add(new NullConstructorParameterTest()
{
Parameters = parameters,
Expand Down