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
20 changes: 3 additions & 17 deletions Source/Mockolate/MockRegistry.Verify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,11 @@ internal VerificationResult<T> IndexerGot<T>(T subject,
public VerificationResult<T> IndexerGot<T>(T subject, int memberId,
Func<IInteraction, bool> gotPredicate,
Func<string> parametersDescription)
{
IFastMemberBuffer? buffer = TryGetBuffer(memberId);
if (buffer is null)
{
return IndexerGot(subject, gotPredicate, parametersDescription);
}

return new VerificationResult<T>(subject,
=> new(subject,
Interactions,
buffer,
TryGetBuffer(memberId),
gotPredicate,
() => $"got indexer {parametersDescription()}");
}

/// <summary>
/// Counts indexer setter accesses on <paramref name="subject" /> where the recorded interaction matches
Expand Down Expand Up @@ -308,15 +300,9 @@ public VerificationResult<T> IndexerSet<T, TValue>(T subject, int memberId,
IParameterMatch<TValue> value,
Func<string> parametersDescription)
{
IFastMemberBuffer? buffer = TryGetBuffer(memberId);
if (buffer is null)
{
return IndexerSet(subject, setPredicate, value, parametersDescription);
}

return new VerificationResult<T>(subject,
Interactions,
buffer,
TryGetBuffer(memberId),
Predicate,
() => $"set indexer {parametersDescription()} to {value}");

Expand Down
162 changes: 162 additions & 0 deletions Tests/Mockolate.Internal.Tests/Verify/TypedVerifyFastPathTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Reflection;
using Mockolate.Exceptions;
using Mockolate.Interactions;
using Mockolate.Parameters;
Expand All @@ -7,6 +8,25 @@ namespace Mockolate.Internal.Tests.Verify;

public class TypedVerifyFastPathTests
{
[Fact]
public async Task IndexerGot_WithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastIndexerGetterBuffer<int> buffer = store.InstallIndexerGetter<int>(0);
MockRegistry registry = new(MockBehavior.Default, store);
buffer.Append(5);
buffer.Append(7);
buffer.Append(5);

VerificationResult<object> result = registry.IndexerGot(
new object(), 0,
static i => i is IndexerGetterAccess<int> g && g.Parameter1 == 5,
() => "[5]");

await That(((IVerificationResult)result).Expectation).IsEqualTo("got indexer [5]");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task IndexerGot_WithMemberIdAndInstalledBuffer_OnlyWalksBuffer()
{
Expand Down Expand Up @@ -55,6 +75,28 @@ public async Task IndexerGotTyped_WithBuffer_ProducesParametersDescriptionInExpe
await That(((IVerificationResult)result).Expectation).IsEqualTo("got indexer (5)");
}

[Fact]
public async Task IndexerSet_WithMemberIdAndBuffer_CountsMatchingValuesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastIndexerSetterBuffer<int, string> buffer = store.InstallIndexerSetter<int, string>(0);
MockRegistry registry = new(MockBehavior.Default, store);
buffer.Append(5, "v");
buffer.Append(7, "v");
buffer.Append(5, "x");

IParameterMatch<string> value = (IParameterMatch<string>)It.Is("v");
VerificationResult<object> result = registry.IndexerSet(
new object(), 0,
static (i, v) => i is IndexerSetterAccess<int, string> s && s.Parameter1 == 5 && v.Matches(s.TypedValue),
value,
() => "[5]");

await That(((IVerificationResult)result).Expectation).Contains("set indexer [5]");
await That(((IVerificationResult)result).Expectation).Contains(value.ToString()!);
await That(((IVerificationResult)result).Verify(arr => arr.Length == 1)).IsTrue();
}

[Fact]
public async Task IndexerSet_WithMemberIdAndInstalledBuffer_OnlyWalksBuffer()
{
Expand Down Expand Up @@ -111,6 +153,41 @@ public async Task IndexerSetTyped_WithBuffer_ProducesParametersDescriptionInExpe
await That(((IVerificationResult)result).Expectation).Contains(value.ToString()!);
}

[Fact]
public async Task SubscribedTo_WithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastEventBuffer buffer = store.InstallEventSubscribe(0);
MockRegistry registry = new(MockBehavior.Default, store);
MethodInfo method = typeof(TypedVerifyFastPathTests).GetMethod(
nameof(SubscribedTo_WithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation))!;
buffer.Append("E", null, method);
buffer.Append("E", null, method);

VerificationResult<object> result = registry.SubscribedTo(new object(), 0, "E");

await That(((IVerificationResult)result).Expectation).IsEqualTo("subscribed to event E");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task SubscribedTo_WithMemberIdButNoBuffer_FallsBackAndFiltersByName()
{
FastMockInteractions store = new(0);
MockRegistry registry = new(MockBehavior.Default, store);
IMockInteractions interactions = store;
MethodInfo method = typeof(TypedVerifyFastPathTests).GetMethod(
nameof(SubscribedTo_WithMemberIdButNoBuffer_FallsBackAndFiltersByName))!;
interactions.RegisterInteraction(new EventSubscription("E", null, method));
interactions.RegisterInteraction(new EventSubscription("E", null, method));
interactions.RegisterInteraction(new EventSubscription("F", null, method));

VerificationResult<object> result = registry.SubscribedTo(new object(), 5, "E");

await That(((IVerificationResult)result).Expectation).IsEqualTo("subscribed to event E");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task SubscribedToTyped_WithBuffer_ProducesEventNameInExpectation()
{
Expand Down Expand Up @@ -152,6 +229,41 @@ public async Task TryGetBuffer_WhenBufferReturned_TypedFastPathIgnoresOtherInter
await That(true).IsTrue();
}

[Fact]
public async Task UnsubscribedFrom_WithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastEventBuffer buffer = store.InstallEventUnsubscribe(0);
MockRegistry registry = new(MockBehavior.Default, store);
MethodInfo method = typeof(TypedVerifyFastPathTests).GetMethod(
nameof(UnsubscribedFrom_WithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation))!;
buffer.Append("E", null, method);
buffer.Append("E", null, method);

VerificationResult<object> result = registry.UnsubscribedFrom(new object(), 0, "E");

await That(((IVerificationResult)result).Expectation).IsEqualTo("unsubscribed from event E");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task UnsubscribedFrom_WithMemberIdButNoBuffer_FallsBackAndFiltersByName()
{
FastMockInteractions store = new(0);
MockRegistry registry = new(MockBehavior.Default, store);
IMockInteractions interactions = store;
MethodInfo method = typeof(TypedVerifyFastPathTests).GetMethod(
nameof(UnsubscribedFrom_WithMemberIdButNoBuffer_FallsBackAndFiltersByName))!;
interactions.RegisterInteraction(new EventUnsubscription("E", null, method));
interactions.RegisterInteraction(new EventUnsubscription("E", null, method));
interactions.RegisterInteraction(new EventUnsubscription("F", null, method));

VerificationResult<object> result = registry.UnsubscribedFrom(new object(), 5, "E");

await That(((IVerificationResult)result).Expectation).IsEqualTo("unsubscribed from event E");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task UnsubscribedFromTyped_WithBuffer_ProducesEventNameInExpectation()
{
Expand Down Expand Up @@ -204,6 +316,23 @@ public async Task VerifyMethod0_TypedFastPath_ShouldCount()
await That(true).IsTrue();
}

[Fact]
public async Task VerifyMethod0_WithMemberIdButNoMatchingBuffer_FallbackPredicateMatchesAllMethodInteractions()
{
FastMockInteractions store = new(0);
MockRegistry registry = new(MockBehavior.Default, store);
IMockInteractions interactions = store;
interactions.RegisterInteraction(new MethodInvocation("Foo"));
interactions.RegisterInteraction(new MethodInvocation("Foo"));
interactions.RegisterInteraction(new MethodInvocation("Bar"));

VerificationResult<object>.IgnoreParameters result = registry.VerifyMethod(
new object(), 5, "Foo", () => "Foo()");

await That(((IVerificationResult)result).Expectation).IsEqualTo("invoked method Foo()");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task VerifyMethod1_TypedFastPath_FailsWithExpectedMessage()
{
Expand Down Expand Up @@ -311,6 +440,39 @@ public async Task VerifyMethod4_FallbackPath_RequiresAllParametersToMatch()
await That(((IVerificationResult)result).Verify(arr => arr.Length == 1)).IsTrue();
}

[Fact]
public async Task VerifyProperty_GetterWithMemberIdAndBuffer_CountsBufferEntriesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastPropertyGetterBuffer buffer = store.InstallPropertyGetter(0);
MockRegistry registry = new(MockBehavior.Default, store);
buffer.Append("P");
buffer.Append("P");

VerificationResult<object> result = registry.VerifyProperty(new object(), 0, "P");

await That(((IVerificationResult)result).Expectation).IsEqualTo("got property P");
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task VerifyProperty_SetterWithMemberIdAndBuffer_CountsMatchingValuesAndProducesExpectation()
{
FastMockInteractions store = new(1);
FastPropertySetterBuffer<int> buffer = store.InstallPropertySetter<int>(0);
MockRegistry registry = new(MockBehavior.Default, store);
buffer.Append("P", 1);
buffer.Append("P", 2);
buffer.Append("P", 1);

IParameterMatch<int> value = (IParameterMatch<int>)It.Is(1);
VerificationResult<object> result = registry.VerifyProperty(new object(), 0, "P", value);

await That(((IVerificationResult)result).Expectation).Contains("set property P");
await That(((IVerificationResult)result).Expectation).Contains(value.ToString()!);
await That(((IVerificationResult)result).Verify(arr => arr.Length == 2)).IsTrue();
}

[Fact]
public async Task VerifyProperty_WithMemberIdButNoBuffer_FallbackPredicateFiltersByName()
{
Expand Down
Loading