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
32 changes: 32 additions & 0 deletions Source/Mockolate/It.IsOneOf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using Mockolate.Parameters;

namespace Mockolate;

#pragma warning disable S3453 // This class can't be instantiated; make its constructor 'public'.
#pragma warning disable S3218 // Inner class members should not shadow outer class "static" or type members
public partial class It
{
/// <summary>
/// Matches a parameter that is equal to one of the <paramref name="values" />.
/// </summary>
public static IParameter<T> IsOneOf<T>(params T[] values)
=> new ParameterIsOneOfMatch<T>(values);

private sealed class ParameterIsOneOfMatch<T>(T[] values) : TypedMatch<T>
{
/// <inheritdoc cref="TypedMatch{T}.Matches(T)" />
protected override bool Matches(T value)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
return values.Any(v => comparer.Equals(value, v));
}

/// <inheritdoc cref="object.ToString()" />
public override string ToString()
=> $"It.IsOneOf({string.Join(", ", values.Select(v => v is string ? $"\"{v}\"" : v?.ToString() ?? "null"))})";
}
}
#pragma warning restore S3218 // Inner class members should not shadow outer class "static" or type members
#pragma warning restore S3453 // This class can't be instantiated; make its constructor 'public'.
1 change: 1 addition & 0 deletions Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace Mockolate
public static Mockolate.It.IInRangeParameter<T> IsInRange<T>(T minimum, T maximum, [System.Runtime.CompilerServices.CallerArgumentExpression("minimum")] string doNotPopulateThisValue1 = "", [System.Runtime.CompilerServices.CallerArgumentExpression("maximum")] string doNotPopulateThisValue2 = "")
where T : System.IComparable<T> { }
public static Mockolate.Parameters.IParameter<T> IsNull<T>() { }
public static Mockolate.Parameters.IParameter<T> IsOneOf<T>(params T[] values) { }
public static Mockolate.Parameters.IVerifyOutParameter<T> IsOut<T>() { }
public static Mockolate.Parameters.IOutParameter<T> IsOut<T>(System.Func<T> setter, [System.Runtime.CompilerServices.CallerArgumentExpression("setter")] string doNotPopulateThisValue = "") { }
public static Mockolate.Parameters.IVerifyReadOnlySpanParameter<T> IsReadOnlySpan<T>(System.Func<T[], bool> predicate) { }
Expand Down
1 change: 1 addition & 0 deletions Tests/Mockolate.Api.Tests/Expected/Mockolate_net8.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace Mockolate
public static Mockolate.It.IInRangeParameter<T> IsInRange<T>(T minimum, T maximum, [System.Runtime.CompilerServices.CallerArgumentExpression("minimum")] string doNotPopulateThisValue1 = "", [System.Runtime.CompilerServices.CallerArgumentExpression("maximum")] string doNotPopulateThisValue2 = "")
where T : System.IComparable<T> { }
public static Mockolate.Parameters.IParameter<T> IsNull<T>() { }
public static Mockolate.Parameters.IParameter<T> IsOneOf<T>(params T[] values) { }
public static Mockolate.Parameters.IVerifyOutParameter<T> IsOut<T>() { }
public static Mockolate.Parameters.IOutParameter<T> IsOut<T>(System.Func<T> setter, [System.Runtime.CompilerServices.CallerArgumentExpression("setter")] string doNotPopulateThisValue = "") { }
public static Mockolate.Parameters.IVerifyReadOnlySpanParameter<T> IsReadOnlySpan<T>(System.Func<T[], bool> predicate) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace Mockolate
public static Mockolate.It.IInRangeParameter<T> IsInRange<T>(T minimum, T maximum, [System.Runtime.CompilerServices.CallerArgumentExpression("minimum")] string doNotPopulateThisValue1 = "", [System.Runtime.CompilerServices.CallerArgumentExpression("maximum")] string doNotPopulateThisValue2 = "")
where T : System.IComparable<T> { }
public static Mockolate.Parameters.IParameter<T> IsNull<T>() { }
public static Mockolate.Parameters.IParameter<T> IsOneOf<T>(params T[] values) { }
public static Mockolate.Parameters.IVerifyOutParameter<T> IsOut<T>() { }
public static Mockolate.Parameters.IOutParameter<T> IsOut<T>(System.Func<T> setter, [System.Runtime.CompilerServices.CallerArgumentExpression("setter")] string doNotPopulateThisValue = "") { }
public static Mockolate.Parameters.IVerifyRefParameter<T> IsRef<T>() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class AnyOutTests
public sealed class IsAnyOutTests
{
[Theory]
[InlineData(42L, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class AnyParametersTests
public sealed class IsAnyParametersTests
{
[Theory]
[InlineData(null, null)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class AnyRefTests
public sealed class IsAnyRefTests
{
[Theory]
[InlineData(42L, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class AnyTests
public sealed class IsAnyTests
{
[Theory]
[InlineData(null)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class FalseTests
public sealed class IsFalseTests
{
[Theory]
[InlineData(false, 1)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class InRangeTests
public sealed class IsInRangeTests
{
[Theory]
[InlineData(3, 5, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class NullTests
public sealed class IsNullTests
{
[Theory]
[InlineData(null, 1)]
Expand All @@ -29,5 +29,18 @@ public async Task ToString_ShouldReturnExpectedValue()

await That(result).IsEqualTo(expectedValue);
}

[Theory]
[InlineData(null, true)]
[InlineData("", false)]
[InlineData("foo", false)]
public async Task WithValue_Nullable_ShouldMatchWhenEqual(string? value, bool expectMatch)
{
IParameter<string?> sut = It.IsNull<string?>();

bool result = ((IParameter)sut).Matches(value);

await That(result).IsEqualTo(expectMatch);
}
}
}
118 changes: 118 additions & 0 deletions Tests/Mockolate.Tests/ItTests.IsOneOfTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using Mockolate.Parameters;

namespace Mockolate.Tests;

public sealed partial class ItTests
{
public sealed class IsOneOfTests
{
[Fact]
public async Task ToString_WithNullableIntValues_ShouldReturnExpectedValue()
{
IParameter<int?> sut = It.IsOneOf<int?>(3, null, 5);
string expectedValue = "It.IsOneOf(3, null, 5)";

string? result = sut.ToString();

await That(result).IsEqualTo(expectedValue);
}

[Fact]
public async Task ToString_WithStringValues_ShouldReturnExpectedValue()
{
IParameter<string> sut = It.IsOneOf("foo", "bar");
string expectedValue = "It.IsOneOf(\"foo\", \"bar\")";

string? result = sut.ToString();

await That(result).IsEqualTo(expectedValue);
}

[Theory]
[InlineData(1, false)]
[InlineData(4, false)]
[InlineData(5, true)]
[InlineData(6, true)]
[InlineData(7, true)]
[InlineData(8, false)]
[InlineData(-5, false)]
[InlineData(42, false)]
public async Task WithValue_ShouldMatchWhenEqualToAny(int value, bool expectMatch)
{
IParameter<int> sut = It.IsOneOf(5, 6, 7);

bool result = ((IParameter)sut).Matches(value);

await That(result).IsEqualTo(expectMatch);
}

[Fact]
public async Task WithValue_ShouldSupportCovarianceInSetup()
{
IMyService mock = Mock.Create<IMyService>();
MyImplementation value1 = new();
MyImplementation value2 = new();
MyOtherImplementation other1 = new();
mock.SetupMock.Method.DoSomething(It.IsOneOf(value1, value2))
.Returns(3);

int result1 = mock.DoSomething(value1);
int result2 = mock.DoSomething(other1);

await That(result1).IsEqualTo(3);
await That(result2).IsEqualTo(0);
}

[Fact]
public async Task WithValue_ShouldSupportCovarianceInVerify()
{
IMyService mock = Mock.Create<IMyService>();
mock.SetupMock.Method.DoSomething(It.Is<MyImplementation>(_ => true))
.Do(d => d.DoWork())
.Returns(3);
MyImplementation value1 = new();
MyImplementation value2 = new();
MyOtherImplementation other1 = new();
MyOtherImplementation other2 = new();

int result1 = mock.DoSomething(value1);

await That(mock.VerifyMock.Invoked.DoSomething(It.IsOneOf(value1, value2))).Once();
await That(value1.Progress).IsEqualTo(1);
await That(result1).IsEqualTo(3);
await That(mock.VerifyMock.Invoked.DoSomething(It.IsOneOf(other1, other2))).Never();
}

public interface IMyBase
{
int DoWork();
}

public class MyImplementation : IMyBase
{
public int Progress { get; private set; }

public int DoWork()
{
Progress++;
return Progress;
}
}

public class MyOtherImplementation : IMyBase
{
public string Output { get; private set; } = "";

public int DoWork()
{
Output += "did something\n";
return 1;
}
}

public interface IMyService
{
int DoSomething(IMyBase value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class OutTests
public sealed class IsOutTests
{
[Fact]
public async Task ToString_ShouldReturnExpectedValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class RefTests
public sealed class IsRefTests
{
[Fact]
public async Task ToString_ShouldReturnExpectedValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class WithTests
public sealed class IsTests
{
[Fact]
public async Task ToString_WithPredicate_ShouldReturnExpectedValue()
Expand Down Expand Up @@ -109,19 +109,6 @@ public async Task WithPredicate_ShouldSupportCovarianceInVerify()
await That(mock.VerifyMock.Invoked.DoSomething(It.Is<MyOtherImplementation>(_ => true))).Never();
}

[Theory]
[InlineData(null, true)]
[InlineData("", false)]
[InlineData("foo", false)]
public async Task WithValue_Nullable_ShouldMatchWhenEqual(string? value, bool expectMatch)
{
IParameter<string?> sut = It.IsNull<string?>();

bool result = ((IParameter)sut).Matches(value);

await That(result).IsEqualTo(expectMatch);
}

[Theory]
[InlineData(1, false)]
[InlineData(5, true)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class TrueTests
public sealed class IsTrueTests
{
[Fact]
public async Task ToString_ShouldReturnExpectedValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
public sealed class MatchesTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Mockolate.Tests;

public sealed partial class MatchTests
public sealed partial class ItTests
{
[Fact]
public async Task InvokeCallbacks_WithCorrectType_ShouldInvokeCallback()
Expand Down
Loading