AsyncTests.Aggregates.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using Xunit;
  8. using System.Collections;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. // ReSharper disable InvokeAsExtensionMethod
  12. // ReSharper disable InconsistentNaming
  13. // ReSharper disable RedundantTypeArgumentsOfMethod
  14. namespace Tests
  15. {
  16. public partial class AsyncTests
  17. {
  18. private const int WaitTimeoutMs = 5000;
  19. [Fact]
  20. public async Task IsEmpty_Null()
  21. {
  22. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.IsEmpty<int>(null));
  23. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.IsEmpty<int>(null, CancellationToken.None));
  24. }
  25. [Fact]
  26. public async Task ToDictionary_Null()
  27. {
  28. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(default(IAsyncEnumerable<int>), x => 0));
  29. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>)));
  30. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(default(IAsyncEnumerable<int>), x => 0, EqualityComparer<int>.Default));
  31. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), EqualityComparer<int>.Default));
  32. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), x => 0, default(IEqualityComparer<int>)));
  33. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0));
  34. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0));
  35. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>)));
  36. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, EqualityComparer<int>.Default));
  37. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, EqualityComparer<int>.Default));
  38. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), EqualityComparer<int>.Default));
  39. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, x => 0, default(IEqualityComparer<int>)));
  40. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(default(IAsyncEnumerable<int>), x => 0, CancellationToken.None));
  41. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), CancellationToken.None));
  42. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(default(IAsyncEnumerable<int>), x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  43. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), EqualityComparer<int>.Default, CancellationToken.None));
  44. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int>(AsyncEnumerable.Return(42), x => 0, default(IEqualityComparer<int>), CancellationToken.None));
  45. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, CancellationToken.None));
  46. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, CancellationToken.None));
  47. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), CancellationToken.None));
  48. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  49. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  50. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), EqualityComparer<int>.Default, CancellationToken.None));
  51. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToDictionary<int, int, int>(AsyncEnumerable.Return(42), x => 0, x => 0, default(IEqualityComparer<int>), CancellationToken.None));
  52. }
  53. [Fact]
  54. public void ToDictionary1()
  55. {
  56. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  57. var res = xs.ToDictionary(x => x % 2).Result;
  58. Assert.True(res[0] == 4);
  59. Assert.True(res[1] == 1);
  60. }
  61. [Fact]
  62. public void ToDictionary2()
  63. {
  64. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  65. AssertThrows<Exception>(() => xs.ToDictionary(x => x % 2).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentException);
  66. }
  67. [Fact]
  68. public void ToDictionary3()
  69. {
  70. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  71. var res = xs.ToDictionary(x => x % 2, x => x + 1).Result;
  72. Assert.True(res[0] == 5);
  73. Assert.True(res[1] == 2);
  74. }
  75. [Fact]
  76. public void ToDictionary4()
  77. {
  78. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  79. AssertThrows<Exception>(() => xs.ToDictionary(x => x % 2, x => x + 1).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentException);
  80. }
  81. [Fact]
  82. public void ToDictionary5()
  83. {
  84. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  85. var res = xs.ToDictionary(x => x % 2, new Eq()).Result;
  86. Assert.True(res[0] == 4);
  87. Assert.True(res[1] == 1);
  88. }
  89. [Fact]
  90. public void ToDictionary6()
  91. {
  92. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  93. AssertThrows<Exception>(() => xs.ToDictionary(x => x % 2, new Eq()).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is ArgumentException);
  94. }
  95. [Fact]
  96. public void ToDictionary7()
  97. {
  98. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  99. var res = xs.ToDictionary(x => x % 2, x => x, new Eq()).Result;
  100. Assert.True(res[0] == 4);
  101. Assert.True(res[1] == 1);
  102. }
  103. [Fact]
  104. public async Task ToLookup_Null()
  105. {
  106. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(default(IAsyncEnumerable<int>), x => 0));
  107. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>)));
  108. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(default(IAsyncEnumerable<int>), x => 0, EqualityComparer<int>.Default));
  109. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), EqualityComparer<int>.Default));
  110. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), x => 0, default(IEqualityComparer<int>)));
  111. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0));
  112. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0));
  113. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>)));
  114. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, EqualityComparer<int>.Default));
  115. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, EqualityComparer<int>.Default));
  116. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), EqualityComparer<int>.Default));
  117. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, x => 0, default(IEqualityComparer<int>)));
  118. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(default(IAsyncEnumerable<int>), x => 0, CancellationToken.None));
  119. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), CancellationToken.None));
  120. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(default(IAsyncEnumerable<int>), x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  121. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), EqualityComparer<int>.Default, CancellationToken.None));
  122. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int>(AsyncEnumerable.Return(42), x => 0, default(IEqualityComparer<int>), CancellationToken.None));
  123. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, CancellationToken.None));
  124. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, CancellationToken.None));
  125. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), CancellationToken.None));
  126. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(default(IAsyncEnumerable<int>), x => 0, x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  127. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), default(Func<int, int>), x => 0, EqualityComparer<int>.Default, CancellationToken.None));
  128. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, default(Func<int, int>), EqualityComparer<int>.Default, CancellationToken.None));
  129. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ToLookup<int, int, int>(AsyncEnumerable.Return(42), x => 0, x => 0, default(IEqualityComparer<int>), CancellationToken.None));
  130. }
  131. [Fact]
  132. public void ToLookup1()
  133. {
  134. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  135. var res = xs.ToLookup(x => x % 2).Result;
  136. Assert.True(res.Contains(0));
  137. Assert.True(res.Contains(1));
  138. Assert.True(res[0].Contains(4));
  139. Assert.True(res[1].Contains(1));
  140. Assert.True(res.Count == 2);
  141. }
  142. [Fact]
  143. public void ToLookup2()
  144. {
  145. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  146. var res = xs.ToLookup(x => x % 2).Result;
  147. Assert.True(res.Contains(0));
  148. Assert.True(res.Contains(1));
  149. Assert.True(res[0].Contains(4));
  150. Assert.True(res[0].Contains(2));
  151. Assert.True(res[1].Contains(1));
  152. Assert.True(res.Count == 2);
  153. }
  154. [Fact]
  155. public void ToLookup3()
  156. {
  157. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  158. var res = xs.ToLookup(x => x % 2, x => x + 1).Result;
  159. Assert.True(res.Contains(0));
  160. Assert.True(res.Contains(1));
  161. Assert.True(res[0].Contains(5));
  162. Assert.True(res[1].Contains(2));
  163. Assert.True(res.Count == 2);
  164. }
  165. [Fact]
  166. public void ToLookup4()
  167. {
  168. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  169. var res = xs.ToLookup(x => x % 2, x => x + 1).Result;
  170. Assert.True(res.Contains(0));
  171. Assert.True(res.Contains(1));
  172. Assert.True(res[0].Contains(5));
  173. Assert.True(res[0].Contains(3));
  174. Assert.True(res[1].Contains(2));
  175. Assert.True(res.Count == 2);
  176. }
  177. [Fact]
  178. public void ToLookup5()
  179. {
  180. var xs = new[] { 1, 4 }.ToAsyncEnumerable();
  181. var res = xs.ToLookup(x => x % 2, new Eq()).Result;
  182. Assert.True(res.Contains(0));
  183. Assert.True(res.Contains(1));
  184. Assert.True(res[0].Contains(4));
  185. Assert.True(res[1].Contains(1));
  186. Assert.True(res.Count == 2);
  187. }
  188. [Fact]
  189. public void ToLookup6()
  190. {
  191. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  192. var res = xs.ToLookup(x => x % 2, new Eq()).Result;
  193. Assert.True(res.Contains(0));
  194. Assert.True(res.Contains(1));
  195. Assert.True(res[0].Contains(4));
  196. Assert.True(res[0].Contains(2));
  197. Assert.True(res[1].Contains(1));
  198. Assert.True(res.Count == 2);
  199. }
  200. [Fact]
  201. public void ToLookup7()
  202. {
  203. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  204. var res = xs.ToLookup(x => x % 2).Result;
  205. foreach (var g in res)
  206. Assert.True(g.Key == 0 || g.Key == 1);
  207. }
  208. [Fact]
  209. public void ToLookup8()
  210. {
  211. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  212. var res = xs.ToLookup(x => x % 2).Result;
  213. #pragma warning disable IDE0007 // Use implicit type
  214. foreach (IGrouping<int, int> g in (IEnumerable)res)
  215. Assert.True(g.Key == 0 || g.Key == 1);
  216. #pragma warning restore IDE0007 // Use implicit type
  217. }
  218. [Fact]
  219. public void ToLookup9()
  220. {
  221. var xs = new[] { 1, 4, 2 }.ToAsyncEnumerable();
  222. var res = xs.ToLookup(x => x % 2, x => x, new Eq()).Result;
  223. Assert.True(res.Contains(0));
  224. Assert.True(res.Contains(1));
  225. Assert.True(res[0].Contains(4));
  226. Assert.True(res[0].Contains(2));
  227. Assert.True(res[1].Contains(1));
  228. Assert.True(res.Count == 2);
  229. }
  230. [Fact]
  231. public async Task Min_Null()
  232. {
  233. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(default(IAsyncEnumerable<DateTime>), Comparer<DateTime>.Default));
  234. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(AsyncEnumerable.Empty<DateTime>(), default(IComparer<DateTime>)));
  235. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(default(IAsyncEnumerable<DateTime>), Comparer<DateTime>.Default, CancellationToken.None));
  236. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Min(AsyncEnumerable.Empty<DateTime>(), default(IComparer<DateTime>), CancellationToken.None));
  237. }
  238. [Fact]
  239. public async Task Max_Null()
  240. {
  241. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(default(IAsyncEnumerable<DateTime>), Comparer<DateTime>.Default));
  242. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(AsyncEnumerable.Empty<DateTime>(), default(IComparer<DateTime>)));
  243. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(default(IAsyncEnumerable<DateTime>), Comparer<DateTime>.Default, CancellationToken.None));
  244. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.Max(AsyncEnumerable.Empty<DateTime>(), default(IComparer<DateTime>), CancellationToken.None));
  245. }
  246. [Fact]
  247. public async Task MinBy_Null()
  248. {
  249. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x));
  250. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), default(Func<int, int>)));
  251. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default));
  252. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), default(Func<int, int>), Comparer<int>.Default));
  253. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), x => x, default(IComparer<int>)));
  254. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, CancellationToken.None));
  255. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), default(Func<int, int>), CancellationToken.None));
  256. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default, CancellationToken.None));
  257. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), default(Func<int, int>), Comparer<int>.Default, CancellationToken.None));
  258. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MinBy(AsyncEnumerable.Return(42), x => x, default(IComparer<int>), CancellationToken.None));
  259. }
  260. [Fact]
  261. public void MinBy1()
  262. {
  263. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => x / 2);
  264. var res = xs.Result;
  265. Assert.True(res.SequenceEqual(new[] { 3, 2 }));
  266. }
  267. [Fact]
  268. public void MinBy2()
  269. {
  270. var xs = new int[0].ToAsyncEnumerable().MinBy(x => x / 2);
  271. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
  272. }
  273. [Fact]
  274. public void MinBy3()
  275. {
  276. var ex = new Exception("Bang!");
  277. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => { if (x == 3) throw ex; return x; });
  278. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  279. }
  280. [Fact]
  281. public void MinBy4()
  282. {
  283. var ex = new Exception("Bang!");
  284. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinBy(x => { if (x == 4) throw ex; return x; });
  285. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  286. }
  287. [Fact]
  288. public void MinBy5()
  289. {
  290. var ex = new Exception("Bang!");
  291. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(AsyncEnumerable.Throw<int>(ex)).MinBy(x => x, Comparer<int>.Default);
  292. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  293. }
  294. [Fact]
  295. public async Task MaxBy_Null()
  296. {
  297. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x));
  298. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), default(Func<int, int>)));
  299. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default));
  300. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), default(Func<int, int>), Comparer<int>.Default));
  301. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), x => x, default(IComparer<int>)));
  302. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, CancellationToken.None));
  303. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), default(Func<int, int>), CancellationToken.None));
  304. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(default(IAsyncEnumerable<int>), x => x, Comparer<int>.Default, CancellationToken.None));
  305. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), default(Func<int, int>), Comparer<int>.Default, CancellationToken.None));
  306. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerableEx.MaxBy(AsyncEnumerable.Return(42), x => x, default(IComparer<int>), CancellationToken.None));
  307. }
  308. [Fact]
  309. public void MaxBy1()
  310. {
  311. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => x / 2);
  312. var res = xs.Result;
  313. Assert.True(res.SequenceEqual(new[] { 7, 6 }));
  314. }
  315. [Fact]
  316. public void MaxBy2()
  317. {
  318. var xs = new int[0].ToAsyncEnumerable().MaxBy(x => x / 2);
  319. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is InvalidOperationException);
  320. }
  321. [Fact]
  322. public void MaxBy3()
  323. {
  324. var ex = new Exception("Bang!");
  325. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => { if (x == 3) throw ex; return x; });
  326. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  327. }
  328. [Fact]
  329. public void MaxBy4()
  330. {
  331. var ex = new Exception("Bang!");
  332. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxBy(x => { if (x == 4) throw ex; return x; });
  333. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  334. }
  335. [Fact]
  336. public void MaxBy5()
  337. {
  338. var ex = new Exception("Bang!");
  339. var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(AsyncEnumerable.Throw<int>(ex)).MaxBy(x => x, Comparer<int>.Default);
  340. AssertThrows<Exception>(() => xs.Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  341. }
  342. private sealed class Eq : IEqualityComparer<int>
  343. {
  344. public bool Equals(int x, int y)
  345. {
  346. return EqualityComparer<int>.Default.Equals(Math.Abs(x), Math.Abs(y));
  347. }
  348. public int GetHashCode(int obj)
  349. {
  350. return EqualityComparer<int>.Default.GetHashCode(Math.Abs(obj));
  351. }
  352. }
  353. }
  354. }