Skip to content

Commit

Permalink
Merge branch 'master' into simplify-first-last-blocking
Browse files Browse the repository at this point in the history
  • Loading branch information
danielcweber committed Nov 19, 2019
2 parents ce352c8 + f308df2 commit 1381281
Show file tree
Hide file tree
Showing 10 changed files with 550 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Ix.NET/Source/Directory.build.props
Expand Up @@ -23,7 +23,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19554-01" PrivateAssets="All"/>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.26" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.28" PrivateAssets="all" />
</ItemGroup>


Expand Down
@@ -0,0 +1,342 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace Tests
{
public class Amb : AsyncEnumerableExTests
{
[Fact]
public void Amb_Null()
{
Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Amb(default, Return42));
Assert.Throws<ArgumentNullException>(() => AsyncEnumerableEx.Amb(Return42, default));
}

[Fact]
public async Task Amb_First_Wins()
{
var source = AsyncEnumerable.Range(1, 5).Amb(AsyncEnumerableEx.Never<int>());

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_First_Wins_Alt()
{
var source = AsyncEnumerable.Range(1, 5).Amb(AsyncEnumerable.Range(1, 5).SelectAwait(async v =>
{
await Task.Delay(500);
return v;
}));

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Second_Wins()
{
var source = AsyncEnumerableEx.Never<int>().Amb(AsyncEnumerable.Range(1, 5));

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Second_Wins_Alt()
{
var source = AsyncEnumerable.Range(1, 5).SelectAwait(async v =>
{
await Task.Delay(500);
return v;
}).Amb(AsyncEnumerable.Range(6, 5));

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i + 5, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_First_Wins()
{
var source = AsyncEnumerableEx.Amb(
AsyncEnumerable.Range(1, 5),
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>()
);

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_Last_Wins()
{
var source = AsyncEnumerableEx.Amb(
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>(),
AsyncEnumerable.Range(1, 5)
);

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_Enum_First_Wins()
{
var source = AsyncEnumerableEx.Amb(new[] {
AsyncEnumerable.Range(1, 5),
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>()
}.AsEnumerable()
);

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_Enum_Last_Wins()
{
var source = AsyncEnumerableEx.Amb(new[] {
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>(),
AsyncEnumerable.Range(1, 5)
}.AsEnumerable()
);

var xs = source.GetAsyncEnumerator();

try
{
for (var i = 1; i <= 5; i++)
{
Assert.True(await xs.MoveNextAsync());
Assert.Equal(i, xs.Current);
}

Assert.False(await xs.MoveNextAsync());
}
finally
{
await xs.DisposeAsync();
}
}


[Fact]
public async Task Amb_First_GetAsyncEnumerator_Crashes()
{
var source = new FailingGetAsyncEnumerator<int>().Amb(AsyncEnumerableEx.Never<int>());

var xs = source.GetAsyncEnumerator();

try
{
await xs.MoveNextAsync();

Assert.False(true, "Should not have gotten here");
}
catch (InvalidOperationException)
{
// we expect this
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Second_GetAsyncEnumerator_Crashes()
{
var source = AsyncEnumerableEx.Never<int>().Amb(new FailingGetAsyncEnumerator<int>());

var xs = source.GetAsyncEnumerator();

try
{
await xs.MoveNextAsync();

Assert.False(true, "Should not have gotten here");
}
catch (InvalidOperationException)
{
// we expect this
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_First_GetAsyncEnumerator_Crashes()
{
var source = AsyncEnumerableEx.Amb(
new FailingGetAsyncEnumerator<int>(),
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>()
);

var xs = source.GetAsyncEnumerator();

try
{
await xs.MoveNextAsync();

Assert.False(true, "Should not have gotten here");
}
catch (InvalidOperationException)
{
// we expect this
}
finally
{
await xs.DisposeAsync();
}
}

[Fact]
public async Task Amb_Many_Last_GetAsyncEnumerator_Crashes()
{
var source = AsyncEnumerableEx.Amb(
AsyncEnumerableEx.Never<int>(),
AsyncEnumerableEx.Never<int>(),
new FailingGetAsyncEnumerator<int>()
);

var xs = source.GetAsyncEnumerator();

try
{
await xs.MoveNextAsync();

Assert.False(true, "Should not have gotten here");
}
catch (InvalidOperationException)
{
// we expect this
}
finally
{
await xs.DisposeAsync();
}
}

private class FailingGetAsyncEnumerator<T> : IAsyncEnumerable<T>
{
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
throw new InvalidOperationException();
}
}
}
}

0 comments on commit 1381281

Please sign in to comment.