Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 3 additions & 3 deletions Source/Mockolate.SourceGenerators/Entities/EquatableArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ public override int GetHashCode()
public ReadOnlySpan<T> AsSpan() => _array.AsSpan();

/// <summary>
/// Returns the underlying wrapped array.
/// Returns the underlying wrapped array, or an empty array when the value was default-constructed.
/// </summary>
/// <returns>Returns the underlying array.</returns>
public T[]? AsArray() => _array;
/// <returns>Returns the underlying array (never null).</returns>
public T[] AsArray() => _array ?? Array.Empty<T>();

/// <inheritdoc />
IEnumerator<T> IEnumerable<T>.GetEnumerator() => ((IEnumerable<T>)(_array ?? Array.Empty<T>())).GetEnumerator();
Expand Down
4 changes: 2 additions & 2 deletions Source/Mockolate.SourceGenerators/Entities/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public bool Equals(Method? x, Method? y)
}

// Compare parameters ignoring nullability annotations
MethodParameter[] xParams = x.Parameters.AsArray()!;
MethodParameter[] yParams = y.Parameters.AsArray()!;
MethodParameter[] xParams = x.Parameters.AsArray();
MethodParameter[] yParams = y.Parameters.AsArray();

for (int i = 0; i < xParams.Length; i++)
{
Expand Down
32 changes: 15 additions & 17 deletions Source/Mockolate.SourceGenerators/MockGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void IIncrementalGenerator.Initialize(IncrementalGeneratorInitializationContext
// MockBehaviorExtensions: only depends on whether HttpClient appears as a mock target.
// Reduce to a bool so the aggregate cache holds across mock-set churn that doesn't toggle it.
IncrementalValueProvider<bool> includeHttpClient = collectedMocks
.Select(static (arr, _) => arr.AsArray()?.Any(m => m.ClassFullName == "global::System.Net.Http.HttpClient") ?? false);
.Select(static (arr, _) => arr.AsArray().Any(m => m.ClassFullName == "global::System.Net.Http.HttpClient"));

context.RegisterSourceOutput(includeHttpClient, static (spc, hasHttp) =>
spc.AddSource("MockBehaviorExtensions.g.cs",
Expand Down Expand Up @@ -189,19 +189,17 @@ private static EquatableArray<MockClass> Distinct(ImmutableArray<MockClass> mock
return cmp;
}

Class[]? aAdds = a.AdditionalImplementations.AsArray();
Class[]? bAdds = b.AdditionalImplementations.AsArray();
int aLen = aAdds?.Length ?? 0;
int bLen = bAdds?.Length ?? 0;
cmp = aLen.CompareTo(bLen);
Class[] aAdds = a.AdditionalImplementations.AsArray();
Class[] bAdds = b.AdditionalImplementations.AsArray();
cmp = aAdds.Length.CompareTo(bAdds.Length);
if (cmp != 0)
{
return cmp;
}

for (int i = 0; i < aLen; i++)
for (int i = 0; i < aAdds.Length; i++)
{
cmp = StringComparer.Ordinal.Compare(aAdds![i].ClassFullName, bAdds![i].ClassFullName);
cmp = StringComparer.Ordinal.Compare(aAdds[i].ClassFullName, bAdds[i].ClassFullName);
if (cmp != 0)
{
return cmp;
Expand All @@ -216,7 +214,7 @@ private static EquatableArray<MockClass> Distinct(ImmutableArray<MockClass> mock

private static HashSet<int> ToHashSet(EquatableArray<int> arities)
{
int[] arr = arities.AsArray() ?? [];
int[] arr = arities.AsArray();
HashSet<int> set = new();
foreach (int item in arr)
{
Expand All @@ -228,7 +226,7 @@ private static HashSet<int> ToHashSet(EquatableArray<int> arities)

private static HashSet<(int, bool)> ToMethodSetupHashSet(EquatableArray<MethodSetupKey> keys)
{
MethodSetupKey[] arr = keys.AsArray() ?? [];
MethodSetupKey[] arr = keys.AsArray();
HashSet<(int, bool)> set = new();
foreach (MethodSetupKey item in arr)
{
Expand All @@ -240,7 +238,7 @@ private static HashSet<int> ToHashSet(EquatableArray<int> arities)

private static EquatableArray<int> CollectIndexerSetupArities(EquatableArray<MockClass> mocks)
{
MockClass[] arr = mocks.AsArray() ?? [];
MockClass[] arr = mocks.AsArray();
HashSet<int> set = new();
foreach (MockClass mc in arr)
{
Expand All @@ -260,7 +258,7 @@ private static EquatableArray<int> CollectIndexerSetupArities(EquatableArray<Moc

private static EquatableArray<MethodSetupKey> CollectMethodSetupKeys(EquatableArray<MockClass> mocks)
{
MockClass[] arr = mocks.AsArray() ?? [];
MockClass[] arr = mocks.AsArray();
HashSet<MethodSetupKey> set = new();
foreach (MockClass mc in arr)
{
Expand Down Expand Up @@ -289,7 +287,7 @@ private static EquatableArray<MethodSetupKey> CollectMethodSetupKeys(EquatableAr

private static RefStructAggregate CollectRefStructAggregate(EquatableArray<MockClass> mocks)
{
MockClass[] arr = mocks.AsArray() ?? [];
MockClass[] arr = mocks.AsArray();
HashSet<MethodSetupKey> methods = new();
Dictionary<int, (bool HasGetter, bool HasSetter)> indexerMap = new();
foreach (MockClass mc in arr)
Expand Down Expand Up @@ -347,7 +345,7 @@ private static RefStructAggregate CollectRefStructAggregate(EquatableArray<MockC

private static EquatableArray<NamedMock> CreateNamedMocks(EquatableArray<MockClass> mocks)
{
MockClass[] arr = mocks.AsArray() ?? [];
MockClass[] arr = mocks.AsArray();
if (arr.Length == 0)
{
return new EquatableArray<NamedMock>([]);
Expand Down Expand Up @@ -417,7 +415,7 @@ private static EquatableArray<NamedMock> CreateNamedMocks(EquatableArray<MockCla

private static EquatableArray<MockAsExtensionPair> CollectAsExtensionPairs(EquatableArray<NamedMock> mocks)
{
NamedMock[] arr = mocks.AsArray() ?? [];
NamedMock[] arr = mocks.AsArray();
HashSet<MockAsExtensionPair> seen = new();
List<MockAsExtensionPair> ordered = new();
foreach (NamedMock nm in arr)
Expand All @@ -427,7 +425,7 @@ private static EquatableArray<MockAsExtensionPair> CollectAsExtensionPairs(Equat
continue;
}

NamedClass[] additionalArr = additional.AsArray()!;
NamedClass[] additionalArr = additional.AsArray();
NamedClass last = additionalArr[additionalArr.Length - 1];

AddIfNew(seen, ordered, MockAsExtensionPair.Create(nm.ParentName, nm.Mock.ClassFullName, last.Name, last.Class.ClassFullName));
Expand Down Expand Up @@ -478,7 +476,7 @@ private static void EmitMockFile(SourceProductionContext context, NamedMock name
return;
}

NamedClass[] additionalNamed = additional.AsArray()!;
NamedClass[] additionalNamed = additional.AsArray();
(string Name, Class Class)[] additionalArr = new (string Name, Class Class)[additionalNamed.Length];
for (int i = 0; i < additionalNamed.Length; i++)
{
Expand Down
8 changes: 8 additions & 0 deletions Source/Mockolate/Verify/IFastCountSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ internal interface IFastCountSource
/// Counts recorded interactions whose parameters satisfy the source's captured matchers.
/// </summary>
int Count();
}

/// <summary>
/// Method-only extension to <see cref="IFastCountSource" />. The <c>AnyParameters()</c> widener is
/// exposed by <see cref="VerificationResult{TVerify}.IgnoreParameters" />, which is only produced by
/// <c>VerifyMethod*</c> overloads — so only method count sources need an unmatched-count path.
/// </summary>
internal interface IFastMethodCountSource : IFastCountSource
{
/// <summary>
/// Counts every recorded interaction, ignoring captured matchers.
/// Used when <c>AnyParameters()</c> widens the verification to any argument list.
Expand Down
21 changes: 5 additions & 16 deletions Source/Mockolate/Verify/MethodCountSources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Mockolate.Verify;
/// <summary>
/// Allocation-free count source backed by a parameterless method buffer.
/// </summary>
internal sealed class Method0CountSource : IFastCountSource
internal sealed class Method0CountSource : IFastMethodCountSource
{
private readonly FastMethod0Buffer _buffer;

Expand All @@ -22,7 +22,7 @@ public Method0CountSource(FastMethod0Buffer buffer)
/// <summary>
/// Allocation-free count source backed by a 1-parameter method buffer and a typed matcher.
/// </summary>
internal sealed class Method1CountSource<T1> : IFastCountSource
internal sealed class Method1CountSource<T1> : IFastMethodCountSource
{
private readonly FastMethod1Buffer<T1> _buffer;
private readonly IParameterMatch<T1> _match1;
Expand All @@ -40,7 +40,7 @@ public Method1CountSource(FastMethod1Buffer<T1> buffer, IParameterMatch<T1> matc
/// <summary>
/// Allocation-free count source backed by a 2-parameter method buffer.
/// </summary>
internal sealed class Method2CountSource<T1, T2> : IFastCountSource
internal sealed class Method2CountSource<T1, T2> : IFastMethodCountSource
{
private readonly FastMethod2Buffer<T1, T2> _buffer;
private readonly IParameterMatch<T1> _match1;
Expand All @@ -61,7 +61,7 @@ public Method2CountSource(FastMethod2Buffer<T1, T2> buffer,
/// <summary>
/// Allocation-free count source backed by a 3-parameter method buffer.
/// </summary>
internal sealed class Method3CountSource<T1, T2, T3> : IFastCountSource
internal sealed class Method3CountSource<T1, T2, T3> : IFastMethodCountSource
{
private readonly FastMethod3Buffer<T1, T2, T3> _buffer;
private readonly IParameterMatch<T1> _match1;
Expand All @@ -84,7 +84,7 @@ public Method3CountSource(FastMethod3Buffer<T1, T2, T3> buffer,
/// <summary>
/// Allocation-free count source backed by a 4-parameter method buffer.
/// </summary>
internal sealed class Method4CountSource<T1, T2, T3, T4> : IFastCountSource
internal sealed class Method4CountSource<T1, T2, T3, T4> : IFastMethodCountSource
{
private readonly FastMethod4Buffer<T1, T2, T3, T4> _buffer;
private readonly IParameterMatch<T1> _match1;
Expand Down Expand Up @@ -120,7 +120,6 @@ public PropertyGetterCountSource(FastPropertyGetterBuffer buffer)
}

public int Count() => _buffer.ConsumeMatching();
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -138,7 +137,6 @@ public PropertySetterCountSource(FastPropertySetterBuffer<T> buffer, IParameterM
}

public int Count() => _buffer.ConsumeMatching(_match);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -156,7 +154,6 @@ public IndexerGetter1CountSource(FastIndexerGetterBuffer<T1> buffer, IParameterM
}

public int Count() => _buffer.ConsumeMatching(_match1);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -177,7 +174,6 @@ public IndexerGetter2CountSource(FastIndexerGetterBuffer<T1, T2> buffer,
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -200,7 +196,6 @@ public IndexerGetter3CountSource(FastIndexerGetterBuffer<T1, T2, T3> buffer,
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2, _match3);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -226,7 +221,6 @@ public IndexerGetter4CountSource(FastIndexerGetterBuffer<T1, T2, T3, T4> buffer,
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2, _match3, _match4);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -247,7 +241,6 @@ public IndexerSetter1CountSource(FastIndexerSetterBuffer<T1, TValue> buffer,
}

public int Count() => _buffer.ConsumeMatching(_match1, _matchValue);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -270,7 +263,6 @@ public IndexerSetter2CountSource(FastIndexerSetterBuffer<T1, T2, TValue> buffer,
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2, _matchValue);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -296,7 +288,6 @@ public IndexerSetter3CountSource(FastIndexerSetterBuffer<T1, T2, T3, TValue> buf
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2, _match3, _matchValue);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand Down Expand Up @@ -326,7 +317,6 @@ public IndexerSetter4CountSource(FastIndexerSetterBuffer<T1, T2, T3, T4, TValue>
}

public int Count() => _buffer.ConsumeMatching(_match1, _match2, _match3, _match4, _matchValue);
public int CountAll() => _buffer.Count;
}

/// <summary>
Expand All @@ -342,5 +332,4 @@ public EventCountSource(FastEventBuffer buffer)
}

public int Count() => _buffer.ConsumeMatching();
public int CountAll() => _buffer.Count;
}
12 changes: 9 additions & 3 deletions Source/Mockolate/Verify/VerificationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,9 @@ bool IFastVerifyCountResult.VerifyCount(Func<int, bool> countPredicate)
ThrowIfRecordingDisabled(_interactions);
if (_fastCountSource is not null)
{
int count = _useCountAll ? _fastCountSource.CountAll() : _fastCountSource.Count();
int count = _useCountAll
? ((IFastMethodCountSource)_fastCountSource).CountAll()
: _fastCountSource.Count();
Comment thread
vbreuss marked this conversation as resolved.
if (countPredicate(count))
{
return true;
Expand Down Expand Up @@ -393,7 +395,9 @@ private async Task<bool> VerifyCountAsync(Func<int, bool> countPredicate)
_interactions.InteractionAdded += OnInteractionAdded;
do
{
int count = _useCountAll ? _fastCountSource!.CountAll() : _fastCountSource!.Count();
int count = _useCountAll
? ((IFastMethodCountSource)_fastCountSource!).CountAll()
: _fastCountSource!.Count();
if (countPredicate(count))
{
Comment thread
vbreuss marked this conversation as resolved.
return true;
Expand Down Expand Up @@ -472,7 +476,9 @@ bool IFastVerifyCountResult.VerifyCount(Func<int, bool> countPredicate)
ThrowIfRecordingDisabled(_interactions);
if (_fastCountSource is not null)
{
int count = _useCountAll ? _fastCountSource.CountAll() : _fastCountSource.Count();
int count = _useCountAll
? ((IFastMethodCountSource)_fastCountSource).CountAll()
: _fastCountSource.Count();
Comment thread
vbreuss marked this conversation as resolved.
return countPredicate(count);
}

Expand Down
Loading
Loading