Skip to content

Commit 1c40968

Browse files
authored
Merge pull request #797 from polyadic/update-xunit
2 parents 56bc6b5 + 0b0b9d0 commit 1c40968

File tree

21 files changed

+462
-101
lines changed

21 files changed

+462
-101
lines changed

Directory.Packages.props

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
88
<PackageVersion Include="System.Collections.Immutable" Version="1.7.1" />
99
<PackageVersion Include="System.Text.Json" Version="5.0.0" />
10-
<PackageVersion Include="xunit.assert" Version="[2.4.0, 2.5)" />
11-
<PackageVersion Include="xunit.extensibility.core" Version="[2.4.0, 2.5)" />
10+
<PackageVersion Include="xunit.assert" Version="[2.9.3, 2.10)" />
11+
<PackageVersion Include="xunit.extensibility.core" Version="[2.9.3, 2.10)" />
1212
<PackageVersion Include="System.Linq.Async" Version="[5.0.0, 7)" />
1313
</ItemGroup>
1414
<ItemGroup Label="Build Dependencies">
@@ -18,8 +18,8 @@
1818
</ItemGroup>
1919
<ItemGroup Label="Test Dependencies">
2020
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
21-
<PackageVersion Include="xunit" Version="2.4.2" />
22-
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
21+
<PackageVersion Include="xunit" Version="2.9.3" />
22+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
2323
<PackageVersion Include="FsCheck.Xunit" Version="2.16.4" />
2424
<PackageVersion Include="coverlet.collector" Version="3.1.2" />
2525
<PackageVersion Include="Verify.XUnit" Version="16.8.1" />

Funcky.Async.Test/AsyncSequence/CycleRangeTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public async Task CycleRangeIsEnumeratedLazilyAsync()
1616
}
1717

1818
[Fact]
19-
public void CyclingAnEmptySetThrowsAnArgumentException()
20-
=> Assert.ThrowsAsync<InvalidOperationException>(CycleEmptySequenceAsync);
19+
public async Task CyclingAnEmptySetThrowsAnArgumentException()
20+
=> await Assert.ThrowsAsync<InvalidOperationException>(CycleEmptySequenceAsync);
2121

2222
[Property]
2323
public Property CycleRangeCanProduceArbitraryManyItemsAsync(NonEmptySet<int> sequence, PositiveInt arbitraryElements)

Funcky.Async.Test/AsyncSequence/RepeatRangeTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public async Task RepeatRangeThrowsWhenAlreadyDisposedEvenIfYouDisposeBetweenMov
4141
var repeatRange = AsyncSequence.RepeatRange(list, repeats);
4242
await using var enumerator = repeatRange.GetAsyncEnumerator();
4343

44-
Assert.True(await AsyncEnumerable.Range(0, i).AllAwaitAsync(async _ => await enumerator.MoveNextAsync()).ConfigureAwait(false));
44+
Assert.True(await AsyncEnumerable.Range(0, i).AllAwaitAsync(async _ => await enumerator.MoveNextAsync()));
4545

4646
#pragma warning disable IDISP016 // we test behaviour after Dispose
4747
#pragma warning disable IDISP017 // we test behaviour after Dispose

Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/ShuffleTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ namespace Funcky.Async.Test.Extensions.AsyncEnumerableExtensions;
88
public sealed class ShuffleTest
99
{
1010
[Fact]
11-
public void AShuffleIsEnumeratedLazilyAsync()
11+
public async Task AShuffleIsEnumeratedLazilyAsync()
1212
{
1313
var doNotEnumerate = new FailOnEnumerateAsyncSequence<object>();
1414

1515
var shuffled = doNotEnumerate.ShuffleAsync();
1616

17-
Assert.ThrowsAsync<XunitException>(async () => await shuffled);
17+
await Assert.ThrowsAsync<XunitException>(async () => await shuffled);
1818
}
1919

2020
[Fact]

Funcky.Async.Test/TestUtilities/AsyncAssert.cs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static async Task Empty<TElement>(IAsyncEnumerable<TElement> asyncSequenc
1111
{
1212
if (await asyncEnumerator.MoveNextAsync())
1313
{
14-
throw new EmptyException(await asyncSequence.ToListAsync());
14+
throw EmptyException.ForNonEmptyCollection(collection: await FormatCollectionStart(asyncSequence));
1515
}
1616
}
1717
finally
@@ -27,7 +27,7 @@ public static async Task NotEmpty<TElement>(IAsyncEnumerable<TElement> asyncSequ
2727
{
2828
if (!await asyncEnumerator.MoveNextAsync())
2929
{
30-
throw new NotEmptyException();
30+
throw NotEmptyException.ForNonEmptyCollection();
3131
}
3232
}
3333
finally
@@ -39,25 +39,7 @@ public static async Task NotEmpty<TElement>(IAsyncEnumerable<TElement> asyncSequ
3939
public static async Task Collection<TElement>(IAsyncEnumerable<TElement> asyncSequence, params Action<TElement>[] elementInspectors)
4040
{
4141
var elements = await asyncSequence.ToListAsync();
42-
var elementInspectorsLength = elementInspectors.Length;
43-
var elementsLength = elements.Count;
44-
45-
if (elementInspectorsLength != elementsLength)
46-
{
47-
throw new CollectionException(asyncSequence.ToListAsync(), elementInspectorsLength, elementsLength);
48-
}
49-
50-
foreach (var ((elementInspector, element), indexFailurePoint) in elementInspectors.Zip(elements).WithIndex())
51-
{
52-
try
53-
{
54-
elementInspector(element);
55-
}
56-
catch (Exception ex)
57-
{
58-
throw new CollectionException(asyncSequence.ToListAsync(), elementInspectorsLength, elementsLength, indexFailurePoint, ex);
59-
}
60-
}
42+
Assert.Collection(elements, elementInspectors);
6143
}
6244

6345
public static async Task<T> Single<T>(IAsyncEnumerable<T> asyncSequence)
@@ -66,19 +48,36 @@ public static async Task<T> Single<T>(IAsyncEnumerable<T> asyncSequence)
6648

6749
if (await asyncEnumerator.MoveNextAsync() is false)
6850
{
69-
SingleException.Empty(null);
51+
throw SingleException.Empty(expected: null, collection: string.Empty);
7052
}
7153

7254
var result = asyncEnumerator.Current;
7355

7456
if (await asyncEnumerator.MoveNextAsync())
7557
{
76-
SingleException.MoreThanOne(await asyncSequence.CountAsync(), null);
58+
var actual = await MaterializeCollectionStart(asyncSequence);
59+
throw SingleException.MoreThanOne(expected: null, collection: FormatCollectionStart(actual), count: actual.Count, matchIndices: Array.Empty<int>());
7760
}
7861

7962
return result;
8063
}
8164

8265
public static async Task Equal<TElement>(IAsyncEnumerable<TElement> expectedResult, IAsyncEnumerable<TElement> actual)
8366
=> Assert.Equal(await expectedResult.ToListAsync(), await actual.ToListAsync());
67+
68+
private static async Task<IReadOnlyCollection<TElement>> MaterializeCollectionStart<TElement>(IAsyncEnumerable<TElement> asyncSequence)
69+
{
70+
// This should *ideally* be kept in sync with XUnit's `ArgumentFormatter.MAX_ENUMERABLE_LENGTH + 1` (which is private).
71+
const int maxEnumerableLength = 6;
72+
return await asyncSequence.Take(maxEnumerableLength).ToListAsync();
73+
}
74+
75+
private static async Task<string> FormatCollectionStart<TElement>(IAsyncEnumerable<TElement> asyncSequence)
76+
=> FormatCollectionStart(await MaterializeCollectionStart(asyncSequence));
77+
78+
private static string FormatCollectionStart<TElement>(IEnumerable<TElement> sequence)
79+
{
80+
using var tracker = sequence.AsTracker();
81+
return tracker.FormatStart();
82+
}
8483
}

Funcky.Test/Extensions/EnumerableExtensions/MaterializeTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void MaterializeWithMaterializationReturnsCorrectCollectionWhenEnumerate(
4545
public void MaterializeDoesNotEnumerableEnumerableReturnedByRepeat()
4646
{
4747
var sequence = Enumerable.Repeat("Hello world!", 3);
48-
var materialized = sequence.Materialize<string, IReadOnlyCollection<string>>(_ => throw new FailException("Materialization should never be called"));
48+
var materialized = sequence.Materialize<string, IReadOnlyCollection<string>>(_ => throw FailException.ForFailure("Materialization should never be called"));
4949
Assert.Same(sequence, materialized);
5050
}
5151
#endif
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Xunit.Sdk;
2+
3+
namespace Funcky.Xunit.Test.FunctionalAssertClass;
4+
5+
public sealed class ErrorTest
6+
{
7+
[Fact]
8+
public void DoesNotThrowForError()
9+
{
10+
FunctionalAssert.Error(Result<int>.Error(new ArgumentException("foo")));
11+
}
12+
13+
[Fact]
14+
public void ThrowsForOk()
15+
{
16+
const string expectedMessage =
17+
"""
18+
FunctionalAssert.Error() Failure: Values differ
19+
Expected: Error(...)
20+
Actual: Ok(42)
21+
""";
22+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Error(Result.Ok(42)));
23+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
24+
}
25+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Xunit.Sdk;
2+
3+
namespace Funcky.Xunit.Test.FunctionalAssertClass;
4+
5+
public sealed class LeftTest
6+
{
7+
[Fact]
8+
public void DoesNotThrowForMatchingLeft()
9+
{
10+
FunctionalAssert.Left(10, Either<int, string>.Left(10));
11+
}
12+
13+
[Fact]
14+
public void DoesNotThrowForLeft()
15+
{
16+
FunctionalAssert.Left(Either<int, string>.Left(10));
17+
}
18+
19+
[Fact]
20+
public void ThrowsForMismatchingLeft()
21+
{
22+
const string expectedMessage =
23+
"""
24+
FunctionalAssert.Left() Failure: Values differ
25+
Expected: Left(10)
26+
Actual: Left(11)
27+
""";
28+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Left(10, Either<int, string>.Left(11)));
29+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
30+
}
31+
32+
[Fact]
33+
public void ThrowsForRightWithExpectedValue()
34+
{
35+
const string expectedMessage =
36+
"""
37+
FunctionalAssert.Left() Failure: Values differ
38+
Expected: Left(10)
39+
Actual: Right("right")
40+
""";
41+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Left(10, Either<int, string>.Right("right")));
42+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
43+
}
44+
45+
[Fact]
46+
public void ThrowsForRight()
47+
{
48+
const string expectedMessage =
49+
"""
50+
FunctionalAssert.Left() Failure: Values differ
51+
Expected: Left(...)
52+
Actual: Right("right")
53+
""";
54+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Left(Either<int, string>.Right("right")));
55+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
56+
}
57+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Xunit.Sdk;
2+
3+
namespace Funcky.Xunit.Test.FunctionalAssertClass;
4+
5+
public sealed class NoneTest
6+
{
7+
[Fact]
8+
public void DoesNotThrowForNone()
9+
{
10+
FunctionalAssert.None(Option<string>.None);
11+
}
12+
13+
[Fact]
14+
public void ThrowsForSome()
15+
{
16+
const string expectedMessage =
17+
"""
18+
FunctionalAssert.None() Failure: Values differ
19+
Expected: None
20+
Actual: Some("something")
21+
""";
22+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.None(Option.Some("something")));
23+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
24+
}
25+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Xunit.Sdk;
2+
3+
namespace Funcky.Xunit.Test.FunctionalAssertClass;
4+
5+
public sealed class OkTest
6+
{
7+
[Fact]
8+
public void DoesNotThrowForMatchingOk()
9+
{
10+
FunctionalAssert.Ok(10, Result.Ok(10));
11+
}
12+
13+
[Fact]
14+
public void DoesNotThrowForOk()
15+
{
16+
FunctionalAssert.Ok(Result.Ok(10));
17+
}
18+
19+
[Fact]
20+
public void ThrowsForMismatchingOk()
21+
{
22+
const string expectedMessage =
23+
"""
24+
FunctionalAssert.Ok() Failure: Values differ
25+
Expected: Ok(10)
26+
Actual: Ok(11)
27+
""";
28+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Ok(10, Result.Ok(11)));
29+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
30+
}
31+
32+
[Fact]
33+
public void ThrowsForErrorWithExpectedValue()
34+
{
35+
const string expectedMessage =
36+
"""
37+
FunctionalAssert.Ok() Failure: Values differ
38+
Expected: Ok(10)
39+
Actual: Error(System.ArgumentException: "message")
40+
""";
41+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Ok(10, Result<int>.Error(new ArgumentException("message"))));
42+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
43+
}
44+
45+
[Fact]
46+
public void ThrowsForError()
47+
{
48+
const string expectedMessage =
49+
"""
50+
FunctionalAssert.Ok() Failure: Values differ
51+
Expected: Ok(...)
52+
Actual: Error(System.ArgumentException: "message")
53+
""";
54+
var exception = Assert.ThrowsAny<XunitException>(() => FunctionalAssert.Ok(Result<int>.Error(new ArgumentException("message"))));
55+
Assert.Equal(expectedMessage.ReplaceLineEndings(Environment.NewLine), exception.Message);
56+
}
57+
}

0 commit comments

Comments
 (0)