diff --git a/Ix.NET/Source/System.Linq.Async.Tests/System.Linq.Async.Tests.csproj b/Ix.NET/Source/System.Linq.Async.Tests/System.Linq.Async.Tests.csproj index d264248e5d..dcbadd0b35 100644 --- a/Ix.NET/Source/System.Linq.Async.Tests/System.Linq.Async.Tests.csproj +++ b/Ix.NET/Source/System.Linq.Async.Tests/System.Linq.Async.Tests.csproj @@ -19,6 +19,11 @@ True Average.Generated.tt + + True + True + GroupBy.Generated.tt + True True @@ -51,6 +56,10 @@ TextTemplatingFileGenerator Average.Generated.cs + + TextTemplatingFileGenerator + GroupBy.Generated.cs + TextTemplatingFileGenerator MinMax.Generated.cs @@ -71,6 +80,11 @@ True Average.Generated.tt + + True + True + GroupBy.Generated.tt + True True diff --git a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.cs b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.cs new file mode 100644 index 0000000000..c68f39ef23 --- /dev/null +++ b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.cs @@ -0,0 +1,591 @@ +// 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 +{ + partial class GroupBy + { + [Fact] + public void KeySelector_Sync_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func))); + } + + [Fact] + public async Task KeySelector_Sync_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name); + var resA = methodsA.GroupBy(m => m.Name); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_Sync_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_Sync_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, eq); + var resA = methodsA.GroupBy(m => m.Name, eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Sync_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (int x) => x)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (int x) => x)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => x, default(Func))); + } + + [Fact] + public async Task KeySelector_ElementSelector_Sync_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper()); + var resA = methodsA.GroupBy(m => m.Name, m => m.Name.ToUpper()); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Sync_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (int x) => x, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (int x) => x, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, default(Func), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_Sync_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq); + var resA = methodsA.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Sync_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (k, g) => 0)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (k, g) => 0)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => x, default(Func, int>))); + } + + [Fact] + public async Task KeySelector_ResultSelector_Sync_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy(m => m.Name, (k, g) => k + " - " + g.CountAsync().Result); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Sync_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (k, g) => 0, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (k, g) => 0, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, default(Func, int>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ResultSelector_Sync_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(m => m.Name, (k, g) => k + " - " + g.CountAsync().Result, eq); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Sync_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (int x) => x, (k, g) => 0)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (int x) => x, (k, g) => 0)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => x, default(Func), (k, g) => 0)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => x, (int x) => x, default(Func, int>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Sync_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.CountAsync().Result); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Sync_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (int x) => x, (k, g) => 0, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func), (int x) => x, (k, g) => 0, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, default(Func), (k, g) => 0, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => x, (int x) => x, default(Func, int>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Sync_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.CountAsync().Result, eq); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_Async_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>))); + } + + [Fact] + public async Task KeySelector_Async_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name)); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_Async_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_Async_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, eq); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Async_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (int x) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => new ValueTask(x), default(Func>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_Async_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper()); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), m => new ValueTask(m.Name.ToUpper())); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Async_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (int x) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), default(Func>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_Async_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), m => new ValueTask(m.Name.ToUpper()), eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Async_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (k, g) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (k, g) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => new ValueTask(x), default(Func, ValueTask>))); + } + + [Fact] + public async Task KeySelector_ResultSelector_Async_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), async (k, g) => k + " - " + await g.CountAsync()); // REVIEW: Ambiguity + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Async_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (k, g) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (k, g) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), default(Func, ValueTask>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ResultSelector_Async_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), async (k, g) => k + " - " + await g.CountAsync(), eq); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Async_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (int x) => new ValueTask(x), (k, g) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x) => new ValueTask(x), (k, g) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => new ValueTask(x), default(Func>), (k, g) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x) => new ValueTask(x), (int x) => new ValueTask(x), default(Func, ValueTask>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Async_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), m => new ValueTask(m.Name.ToUpper()), async (k, g) => k + " - " + await g.CountAsync()); // REVIEW: Ambiguity + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Async_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (int x) => new ValueTask(x), (k, g) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x) => new ValueTask(x), (k, g) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), default(Func>), (k, g) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x) => new ValueTask(x), (int x) => new ValueTask(x), default(Func, ValueTask>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Async_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(m => new ValueTask(m.Name), m => new ValueTask(m.Name.ToUpper()), async (k, g) => k + " - " + await g.CountAsync(), eq); + + await Group_Result_AssertCore(resS, resA); + } + +#if !NO_DEEP_CANCELLATION + [Fact] + public void KeySelector_Async_Cancel_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>))); + } + + [Fact] + public async Task KeySelector_Async_Cancel_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name)); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_Async_Cancel_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_Async_Cancel_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, eq); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Async_Cancel_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x, CancellationToken ct) => new ValueTask(x))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x, CancellationToken ct) => new ValueTask(x), default(Func>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_Async_Cancel_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper()); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), (m, ct) => new ValueTask(m.Name.ToUpper())); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_Async_Cancel_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x, CancellationToken ct) => new ValueTask(x), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), default(Func>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_Async_Cancel_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), (m, ct) => new ValueTask(m.Name.ToUpper()), eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Async_Cancel_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (k, g, ct) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x, CancellationToken ct) => new ValueTask(x), default(Func, CancellationToken, ValueTask>))); + } + + [Fact] + public async Task KeySelector_ResultSelector_Async_Cancel_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), async (k, g, ct) => k + " - " + await g.CountAsync(ct)); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_Async_Cancel_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (k, g, ct) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), default(Func, CancellationToken, ValueTask>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ResultSelector_Async_Cancel_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), async (k, g, ct) => k + " - " + await g.CountAsync(ct), eq); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Async_Cancel_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x, CancellationToken ct) => new ValueTask(x), default(Func>), (k, g, ct) => new ValueTask(0))); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x), default(Func, CancellationToken, ValueTask>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Async_Cancel_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count()); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), (m, ct) => new ValueTask(m.Name.ToUpper()), async (k, g, ct) => k + " - " + await g.CountAsync(ct)); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_Async_Cancel_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(Func>), (int x, CancellationToken ct) => new ValueTask(x), (k, g, ct) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), default(Func>), (k, g, ct) => new ValueTask(0), EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), (int x, CancellationToken ct) => new ValueTask(x), (int x, CancellationToken ct) => new ValueTask(x), default(Func, CancellationToken, ValueTask>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_Async_Cancel_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy((m, ct) => new ValueTask(m.Name), (m, ct) => new ValueTask(m.Name.ToUpper()), async (k, g, ct) => k + " - " + await g.CountAsync(ct), eq); + + await Group_Result_AssertCore(resS, resA); + } +#endif + + private async Task Groups_AssertCore(IEnumerable> resS, IAsyncEnumerable> resA) + { + Assert.True(await AsyncEnumerable.SequenceEqualAsync( + resS.Select(g => g.Key).ToAsyncEnumerable(), + resA.Select(g => g.Key) + )); + + // CountAsync + + Assert.Equal(resS.Count(), await resA.CountAsync()); + + // ToArrayAsync + + var resArrS = resS.ToArray(); + var resArrA = await resA.ToArrayAsync(); + + Assert.Equal( + resArrS.Select(g => g.Key), + resArrA.Select(g => g.Key) + ); + + // ToListAsync + + var resLstS = resS.ToList(); + var resLstA = await resA.ToListAsync(); + + Assert.Equal( + resLstS.Select(g => g.Key), + resLstA.Select(g => g.Key) + ); + } + + private async Task Group_Result_AssertCore(IEnumerable resS, IAsyncEnumerable resA) + { + Assert.True(await AsyncEnumerable.SequenceEqualAsync( + resS.ToAsyncEnumerable(), + resA + )); + + // CountAsync + + Assert.Equal(resS.Count(), await resA.CountAsync()); + + // ToArrayAsync + + var resArrS = resS.ToArray(); + var resArrA = await resA.ToArrayAsync(); + + Assert.Equal(resArrS, resArrA); + + // ToListAsync + + var resLstS = resS.ToList(); + var resLstA = await resA.ToListAsync(); + + Assert.Equal(resLstS, resLstA); + } + + private sealed class StringPrefixEqualityComparer : IEqualityComparer + { + private readonly int _n; + + public StringPrefixEqualityComparer(int n) => _n = n; + + public bool Equals(string s1, string s2) => s1.Substring(0, _n) == s2.Substring(0, _n); + + public int GetHashCode(string s) => s.Substring(0, _n).GetHashCode(); + } + } +} diff --git a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.tt b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.tt new file mode 100644 index 0000000000..6e5e416970 --- /dev/null +++ b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.Generated.tt @@ -0,0 +1,358 @@ +// 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. + +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Tests +{ + partial class GroupBy + { +<# +foreach (var kind in new[] { "Sync", "Async", "Async_Cancel" }) +{ + string keySelectorType, elementSelectorType, resultSelectorType; + string keySelectorFunc, elementSelectorFunc, resultSelectorFunc; + bool isCancel = false; + + switch (kind) + { + case "Sync": + keySelectorType = elementSelectorType = "Func"; + keySelectorFunc = elementSelectorFunc = "(int x) => x"; + resultSelectorType = "Func, int>"; + resultSelectorFunc = "(k, g) => 0"; + break; + case "Async": + keySelectorType = elementSelectorType = "Func>"; + keySelectorFunc = elementSelectorFunc = "(int x) => new ValueTask(x)"; + resultSelectorType = "Func, ValueTask>"; + resultSelectorFunc = "(k, g) => new ValueTask(0)"; + break; + case "Async_Cancel": + keySelectorType = elementSelectorType = "Func>"; + keySelectorFunc = elementSelectorFunc = "(int x, CancellationToken ct) => new ValueTask(x)"; + resultSelectorType = "Func, CancellationToken, ValueTask>"; + resultSelectorFunc = "(k, g, ct) => new ValueTask(0)"; + isCancel = true; + break; + default: + throw new Exception(); + } + + if (isCancel) + { +#> +#if !NO_DEEP_CANCELLATION +<# + } + + string keySelector, elementSelector, resultSelector; + + switch (kind) + { + case "Sync": + keySelector = "m => m.Name"; + elementSelector = "m => m.Name.ToUpper()"; + resultSelector = "(k, g) => k + \" - \" + g.CountAsync().Result"; + break; + case "Async": + keySelector = "m => new ValueTask(m.Name)"; + elementSelector = "m => new ValueTask(m.Name.ToUpper())"; + resultSelector = "async (k, g) => k + \" - \" + await g.CountAsync()"; + break; + case "Async_Cancel": + keySelector = "(m, ct) => new ValueTask(m.Name)"; + elementSelector = "(m, ct) => new ValueTask(m.Name.ToUpper())"; + resultSelector = "async (k, g, ct) => k + \" - \" + await g.CountAsync(ct)"; + break; + default: + throw new Exception(); + } +#> + [Fact] + public void KeySelector_<#=kind#>_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>))); + } + + [Fact] + public async Task KeySelector_<#=kind#>_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name); + var resA = methodsA.GroupBy(<#=keySelector#>); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_<#=kind#>_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_<#=kind#>_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, eq); + var resA = methodsA.GroupBy(<#=keySelector#>, eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_<#=kind#>_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=elementSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, <#=keySelectorFunc#>, default(<#=elementSelectorType#>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_<#=kind#>_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper()); + var resA = methodsA.GroupBy(<#=keySelector#>, <#=elementSelector#>); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_<#=kind#>_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, default(<#=elementSelectorType#>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_<#=kind#>_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), eq); + var resA = methodsA.GroupBy(<#=keySelector#>, <#=elementSelector#>, eq); + + await Groups_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_<#=kind#>_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=resultSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=resultSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, <#=keySelectorFunc#>, default(<#=resultSelectorType#>))); + } + + [Fact] + public async Task KeySelector_ResultSelector_<#=kind#>_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count()); +<# +if (kind == "Async") +{ +#> + var resA = methodsA.GroupBy(<#=keySelector#>, <#=resultSelector#>); // REVIEW: Ambiguity +<# +} +else +{ +#> + var resA = methodsA.GroupBy(<#=keySelector#>, <#=resultSelector#>); +<# +} +#> + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ResultSelector_<#=kind#>_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=resultSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, default(<#=resultSelectorType#>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ResultSelector_<#=kind#>_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(<#=keySelector#>, <#=resultSelector#>, eq); + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_<#=kind#>_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, <#=resultSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, <#=resultSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, <#=keySelectorFunc#>, default(<#=elementSelectorType#>), <#=resultSelectorFunc#>)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, <#=keySelectorFunc#>, <#=elementSelectorFunc#>, default(<#=resultSelectorType#>))); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_<#=kind#>_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count()); +<# +if (kind == "Async") +{ +#> + var resA = methodsA.GroupBy(<#=keySelector#>, <#=elementSelector#>, <#=resultSelector#>); // REVIEW: Ambiguity +<# +} +else +{ +#> + var resA = methodsA.GroupBy(<#=keySelector#>, <#=elementSelector#>, <#=resultSelector#>); +<# +} +#> + + await Group_Result_AssertCore(resS, resA); + } + + [Fact] + public void KeySelector_ElementSelector_ResultSelector_<#=kind#>_Comparer_Null() + { + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(Return42, default(<#=keySelectorType#>), <#=elementSelectorFunc#>, <#=resultSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, default(<#=elementSelectorType#>), <#=resultSelectorFunc#>, EqualityComparer.Default)); + Assert.Throws(() => AsyncEnumerable.GroupBy(default(IAsyncEnumerable), <#=keySelectorFunc#>, <#=elementSelectorFunc#>, default(<#=resultSelectorType#>), EqualityComparer.Default)); + } + + [Fact] + public async Task KeySelector_ElementSelector_ResultSelector_<#=kind#>_Comparer_All() + { + var methodsS = typeof(Enumerable).GetMethods().AsEnumerable(); + var methodsA = methodsS.ToAsyncEnumerable(); + + var eq = new StringPrefixEqualityComparer(1); + + var resS = methodsS.GroupBy(m => m.Name, m => m.Name.ToUpper(), (k, g) => k + " - " + g.Count(), eq); + var resA = methodsA.GroupBy(<#=keySelector#>, <#=elementSelector#>, <#=resultSelector#>, eq); + + await Group_Result_AssertCore(resS, resA); + } +<# + if (isCancel) + { +#> +#endif +<# + } +#> + +<# +} +#> + private async Task Groups_AssertCore(IEnumerable> resS, IAsyncEnumerable> resA) + { + Assert.True(await AsyncEnumerable.SequenceEqualAsync( + resS.Select(g => g.Key).ToAsyncEnumerable(), + resA.Select(g => g.Key) + )); + + // CountAsync + + Assert.Equal(resS.Count(), await resA.CountAsync()); + + // ToArrayAsync + + var resArrS = resS.ToArray(); + var resArrA = await resA.ToArrayAsync(); + + Assert.Equal( + resArrS.Select(g => g.Key), + resArrA.Select(g => g.Key) + ); + + // ToListAsync + + var resLstS = resS.ToList(); + var resLstA = await resA.ToListAsync(); + + Assert.Equal( + resLstS.Select(g => g.Key), + resLstA.Select(g => g.Key) + ); + } + + private async Task Group_Result_AssertCore(IEnumerable resS, IAsyncEnumerable resA) + { + Assert.True(await AsyncEnumerable.SequenceEqualAsync( + resS.ToAsyncEnumerable(), + resA + )); + + // CountAsync + + Assert.Equal(resS.Count(), await resA.CountAsync()); + + // ToArrayAsync + + var resArrS = resS.ToArray(); + var resArrA = await resA.ToArrayAsync(); + + Assert.Equal(resArrS, resArrA); + + // ToListAsync + + var resLstS = resS.ToList(); + var resLstA = await resA.ToListAsync(); + + Assert.Equal(resLstS, resLstA); + } + + private sealed class StringPrefixEqualityComparer : IEqualityComparer + { + private readonly int _n; + + public StringPrefixEqualityComparer(int n) => _n = n; + + public bool Equals(string s1, string s2) => s1.Substring(0, _n) == s2.Substring(0, _n); + + public int GetHashCode(string s) => s.Substring(0, _n).GetHashCode(); + } + } +} diff --git a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs index 6fd2cf86a5..6d04d8ef96 100644 --- a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs +++ b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/GroupBy.cs @@ -10,7 +10,7 @@ namespace Tests { - public class GroupBy : AsyncEnumerableTests + public partial class GroupBy : AsyncEnumerableTests { [Fact] public void GroupBy_KeySelector_Sync_Null()