Skip to content

Commit a680715

Browse files
committed
Merge branch 'main' into Clear-SynchronizationContext-in-ToTask()
2 parents 5a2976b + 7bed5ba commit a680715

59 files changed

Lines changed: 901 additions & 188 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/clipboard.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The clipboard behavior can be enabled using the following:
2525
```cs
2626
ClipboardAccept.Enable();
2727
```
28-
<sup><a href='/src/Verify.ClipboardAccept.Tests/ClipboardEnabledTests.cs#L12-L14' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnableClipboard' title='Start of snippet'>anchor</a></sup>
28+
<sup><a href='/src/Verify.ClipboardAccept.Tests/ClipboardEnabledTests.cs#L24-L26' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnableClipboard' title='Start of snippet'>anchor</a></sup>
2929
<!-- endSnippet -->
3030

3131

docs/combinations.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public Task BuildAddressExceptionsDisabledTest()
175175
city);
176176
}
177177
```
178-
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L185-L201' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptionsFalse' title='Start of snippet'>anchor</a></sup>
178+
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L214-L230' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptionsFalse' title='Start of snippet'>anchor</a></sup>
179179
<!-- endSnippet -->
180180

181181

@@ -215,13 +215,32 @@ public class CombinationResultsConverter :
215215

216216
var keyValues = new string[items.Count, keysLength];
217217

218+
// Keys repeat across rows (a column only has as many distinct values as
219+
// its input list), so cache the computed name per distinct key value.
220+
var nameCache = new Dictionary<object, string>();
221+
string? nullName = null;
222+
218223
for (var itemIndex = 0; itemIndex < items.Count; itemIndex++)
219224
{
220225
var item = items[itemIndex];
221226
for (var keyIndex = 0; keyIndex < keysLength; keyIndex++)
222227
{
223228
var key = item.Keys[keyIndex];
224-
var name = VerifierSettings.GetNameForParameter(key, writer.Counter, pathFriendly: false);
229+
string name;
230+
if (key == null)
231+
{
232+
name = nullName ??= VerifierSettings.GetNameForParameter(null, writer.Counter, pathFriendly: false);
233+
}
234+
else if (nameCache.TryGetValue(key, out var cached))
235+
{
236+
name = cached;
237+
}
238+
else
239+
{
240+
name = VerifierSettings.GetNameForParameter(key, writer.Counter, pathFriendly: false);
241+
nameCache[key] = name;
242+
}
243+
225244
keyValues[itemIndex, keyIndex] = name;
226245
var currentKeyLength = maxKeyLengths[keyIndex];
227246
if (name.Length > currentKeyLength)
@@ -353,7 +372,7 @@ public class CombinationResultsConverter :
353372
}
354373
}
355374
```
356-
<sup><a href='/src/Verify/Combinations/CombinationResultsConverter.cs#L1-L166' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationResultsConverter.cs' title='Start of snippet'>anchor</a></sup>
375+
<sup><a href='/src/Verify/Combinations/CombinationResultsConverter.cs#L1-L185' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationResultsConverter.cs' title='Start of snippet'>anchor</a></sup>
357376
<!-- endSnippet -->
358377

359378

@@ -378,7 +397,7 @@ class CustomCombinationConverter :
378397
string.Join(", ", keys.Select(_ => _.Value));
379398
}
380399
```
381-
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L231-L240' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationConverter' title='Start of snippet'>anchor</a></sup>
400+
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L260-L269' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationConverter' title='Start of snippet'>anchor</a></sup>
382401
<!-- endSnippet -->
383402

384403
Full control of serialization can be achieved by inheriting from `WriteOnlyJsonConverter<CombinationResults>`.
@@ -397,7 +416,7 @@ static CustomCombinationConverter customConverter = new();
397416
public static void Init() =>
398417
VerifierSettings.AddExtraSettings(_ => _.Converters.Insert(0, customConverter));
399418
```
400-
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L203-L211' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationModuleInitializer' title='Start of snippet'>anchor</a></sup>
419+
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L232-L240' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationModuleInitializer' title='Start of snippet'>anchor</a></sup>
401420
<!-- endSnippet -->
402421

403422

@@ -528,5 +547,5 @@ Headers can be enabled globally:
528547
public static void EnableIncludeHeaders() =>
529548
CombinationSettings.IncludeHeaders();
530549
```
531-
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L243-L249' title='Snippet source file'>snippet source</a> | <a href='#snippet-GlobalCombinationHeader' title='Start of snippet'>anchor</a></sup>
550+
<sup><a href='/src/StaticSettingsTests/CombinationTests.cs#L272-L278' title='Snippet source file'>snippet source</a> | <a href='#snippet-GlobalCombinationHeader' title='Start of snippet'>anchor</a></sup>
532551
<!-- endSnippet -->

docs/comparer.md

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -119,35 +119,41 @@ public static async Task<CompareResult> AreEqual(Stream stream1, Stream stream2)
119119
EnsureAtStart(stream1);
120120
EnsureAtStart(stream2);
121121

122-
var buffer1 = new byte[bufferSize];
123-
var buffer2 = new byte[bufferSize];
124-
125-
while (true)
122+
var buffer1 = ArrayPool<byte>.Shared.Rent(bufferSize);
123+
var buffer2 = ArrayPool<byte>.Shared.Rent(bufferSize);
124+
try
126125
{
127-
var count1 = await ReadBufferAsync(stream1, buffer1);
128-
var count2 = await ReadBufferAsync(stream2, buffer2);
129-
130-
// Callers do not always guarantee the streams are the same length
131-
// (e.g. a non-seekable received stream), so a length difference must
132-
// be treated as not-equal instead of a short-circuit to equal.
133-
if (count1 != count2)
126+
while (true)
134127
{
135-
return CompareResult.NotEqual();
136-
}
128+
var count1 = await ReadBufferAsync(stream1, buffer1);
129+
var count2 = await ReadBufferAsync(stream2, buffer2);
137130

138-
if (count1 == 0)
139-
{
140-
return CompareResult.Equal;
141-
}
131+
// Callers do not always guarantee the streams are the same length
132+
// (e.g. a non-seekable received stream), so a length difference must
133+
// be treated as not-equal instead of a short-circuit to equal.
134+
if (count1 != count2)
135+
{
136+
return CompareResult.NotEqual();
137+
}
142138

143-
for (var i = 0; i < count1; i += sizeof(long))
144-
{
145-
if (BitConverter.ToInt64(buffer1, i) != BitConverter.ToInt64(buffer2, i))
139+
if (count1 == 0)
140+
{
141+
return CompareResult.Equal;
142+
}
143+
144+
// Compare exactly the bytes read (a rented buffer's trailing bytes
145+
// are arbitrary, so they must not be included).
146+
if (!buffer1.AsSpan(0, count1).SequenceEqual(buffer2.AsSpan(0, count1)))
146147
{
147148
return CompareResult.NotEqual();
148149
}
149150
}
150151
}
152+
finally
153+
{
154+
ArrayPool<byte>.Shared.Return(buffer1);
155+
ArrayPool<byte>.Shared.Return(buffer2);
156+
}
151157
}
152158

153159
static void EnsureAtStart(Stream stream)
@@ -161,10 +167,13 @@ static void EnsureAtStart(Stream stream)
161167

162168
static async Task<int> ReadBufferAsync(Stream stream, byte[] buffer)
163169
{
170+
// Read up to bufferSize (not buffer.Length): a rented buffer may be
171+
// larger, and both streams must be read in equal-sized chunks so the
172+
// length comparison above stays aligned.
164173
var bytesRead = 0;
165-
while (bytesRead < buffer.Length)
174+
while (bytesRead < bufferSize)
166175
{
167-
var read = await stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead);
176+
var read = await stream.ReadAsync(buffer, bytesRead, bufferSize - bytesRead);
168177
if (read == 0)
169178
{
170179
// Reached end of stream.
@@ -177,7 +186,7 @@ static async Task<int> ReadBufferAsync(Stream stream, byte[] buffer)
177186
return bytesRead;
178187
}
179188
```
180-
<sup><a href='/src/Verify/Compare/StreamComparer.cs#L3-L70' title='Snippet source file'>snippet source</a> | <a href='#snippet-DefualtCompare' title='Start of snippet'>anchor</a></sup>
189+
<sup><a href='/src/Verify/Compare/StreamComparer.cs#L3-L79' title='Snippet source file'>snippet source</a> | <a href='#snippet-DefualtCompare' title='Start of snippet'>anchor</a></sup>
181190
<!-- endSnippet -->
182191

183192

docs/guids.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var target = new GuidTarget
2323

2424
await Verify(target);
2525
```
26-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2273-L2286' title='Snippet source file'>snippet source</a> | <a href='#snippet-guid' title='Start of snippet'>anchor</a></sup>
26+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2320-L2333' title='Snippet source file'>snippet source</a> | <a href='#snippet-guid' title='Start of snippet'>anchor</a></sup>
2727
<!-- endSnippet -->
2828

2929
Results in the following:

docs/members-throw.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public Task CustomExceptionPropFluent()
3535
.IgnoreMembersThatThrow<CustomException>();
3636
}
3737
```
38-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3988-L4007' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrow' title='Start of snippet'>anchor</a></sup>
38+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4035-L4054' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrow' title='Start of snippet'>anchor</a></sup>
3939
<!-- endSnippet -->
4040

4141
Or globally:
@@ -45,7 +45,7 @@ Or globally:
4545
```cs
4646
VerifierSettings.IgnoreMembersThatThrow<CustomException>();
4747
```
48-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3982-L3986' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowGlobal' title='Start of snippet'>anchor</a></sup>
48+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4029-L4033' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowGlobal' title='Start of snippet'>anchor</a></sup>
4949
<!-- endSnippet -->
5050

5151
Result:
@@ -82,7 +82,7 @@ public Task ExceptionMessagePropFluent()
8282
.IgnoreMembersThatThrow<Exception>(_ => _.Message == "Ignore");
8383
}
8484
```
85-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2616-L2637' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowExpression' title='Start of snippet'>anchor</a></sup>
85+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2663-L2684' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowExpression' title='Start of snippet'>anchor</a></sup>
8686
<!-- endSnippet -->
8787

8888
Or globally:
@@ -92,7 +92,7 @@ Or globally:
9292
```cs
9393
VerifierSettings.IgnoreMembersThatThrow<Exception>(_ => _.Message == "Ignore");
9494
```
95-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2609-L2613' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowExpressionGlobal' title='Start of snippet'>anchor</a></sup>
95+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2656-L2660' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMembersThatThrowExpressionGlobal' title='Start of snippet'>anchor</a></sup>
9696
<!-- endSnippet -->
9797

9898
Result:

docs/naming.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ public static string NameWithParent(this Type type)
789789
return type.Name;
790790
}
791791
```
792-
<sup><a href='/src/Verify/Extensions.cs#L114-L126' title='Snippet source file'>snippet source</a> | <a href='#snippet-NameWithParent' title='Start of snippet'>anchor</a></sup>
792+
<sup><a href='/src/Verify/Extensions.cs#L132-L144' title='Snippet source file'>snippet source</a> | <a href='#snippet-NameWithParent' title='Start of snippet'>anchor</a></sup>
793793
<!-- endSnippet -->
794794

795795
Any path calculated in `DerivePathInfo` should be fully qualified to remove the inconsistency of the current directory.

docs/obsolete-members.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public Task WithObsoleteProp()
3131
return Verify(target);
3232
}
3333
```
34-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4135-L4156' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoleteProp' title='Start of snippet'>anchor</a></sup>
34+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4182-L4203' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoleteProp' title='Start of snippet'>anchor</a></sup>
3535
<!-- endSnippet -->
3636

3737
Result:
@@ -79,7 +79,7 @@ public Task WithObsoletePropIncludedFluent()
7979
.IncludeObsoletes();
8080
}
8181
```
82-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4106-L4133' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoletePropIncluded' title='Start of snippet'>anchor</a></sup>
82+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4153-L4180' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoletePropIncluded' title='Start of snippet'>anchor</a></sup>
8383
<!-- endSnippet -->
8484

8585
Or globally:
@@ -89,7 +89,7 @@ Or globally:
8989
```cs
9090
VerifierSettings.IncludeObsoletes();
9191
```
92-
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4100-L4104' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoletePropIncludedGlobally' title='Start of snippet'>anchor</a></sup>
92+
<sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L4147-L4151' title='Snippet source file'>snippet source</a> | <a href='#snippet-WithObsoletePropIncludedGlobally' title='Start of snippet'>anchor</a></sup>
9393
<!-- endSnippet -->
9494

9595
Result:

0 commit comments

Comments
 (0)