OrderBy.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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 System.Threading.Tasks;
  8. using Xunit;
  9. namespace Tests
  10. {
  11. public partial class OrderBy : AsyncEnumerableTests
  12. {
  13. [Fact]
  14. public void OrderBy_Null()
  15. {
  16. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderBy<int, int>(default, x => x));
  17. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderBy(Return42, default(Func<int, int>)));
  18. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderBy<int, int>(default, x => x, Comparer<int>.Default));
  19. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderBy(Return42, default, Comparer<int>.Default));
  20. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderByDescending<int, int>(default, x => x));
  21. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderByDescending(Return42, default(Func<int, int>)));
  22. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderByDescending<int, int>(default, x => x, Comparer<int>.Default));
  23. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.OrderByDescending(Return42, default, Comparer<int>.Default));
  24. var xs = Return42.OrderBy(x => x);
  25. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenBy<int, int>(default, x => x));
  26. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenBy(xs, default(Func<int, int>)));
  27. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenBy<int, int>(default, x => x, Comparer<int>.Default));
  28. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenBy(xs, default, Comparer<int>.Default));
  29. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenByDescending<int, int>(default, x => x));
  30. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenByDescending(xs, default(Func<int, int>)));
  31. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenByDescending<int, int>(default, x => x, Comparer<int>.Default));
  32. Assert.Throws<ArgumentNullException>(() => AsyncEnumerable.ThenByDescending(xs, default, Comparer<int>.Default));
  33. }
  34. [Fact]
  35. public async Task OrderBy_Empty()
  36. {
  37. var ys = AsyncEnumerable.Empty<int>().OrderBy(x => x);
  38. var e = ys.GetAsyncEnumerator();
  39. await NoNextAsync(e);
  40. }
  41. [Fact]
  42. public async Task OrderBy1()
  43. {
  44. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  45. var ys = xs.OrderBy(x => x);
  46. var e = ys.GetAsyncEnumerator();
  47. for (var i = 0; i < 10; i++)
  48. await HasNextAsync(e, i);
  49. await NoNextAsync(e);
  50. }
  51. [Fact]
  52. public async Task OrderBy2Async()
  53. {
  54. var ex = new Exception("Bang!");
  55. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  56. var ys = xs.OrderBy(new Func<int, int>(x => { throw ex; }));
  57. var e = ys.GetAsyncEnumerator();
  58. await AssertThrowsAsync(e.MoveNextAsync(), ex);
  59. }
  60. [Fact]
  61. public async Task OrderBy3()
  62. {
  63. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  64. var ys = xs.OrderBy(x => x);
  65. await SequenceIdentity(ys);
  66. }
  67. [Fact]
  68. public async Task ThenBy2Async()
  69. {
  70. var ex = new Exception("Bang!");
  71. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  72. var ys = xs.OrderBy(x => x).ThenBy(new Func<int, int>(x => { throw ex; }));
  73. var e = ys.GetAsyncEnumerator();
  74. await AssertThrowsAsync(e.MoveNextAsync(), ex);
  75. }
  76. [Fact]
  77. public async Task OrderByDescending1()
  78. {
  79. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  80. var ys = xs.OrderByDescending(x => x);
  81. var e = ys.GetAsyncEnumerator();
  82. for (var i = 9; i >= 0; i--)
  83. await HasNextAsync(e, i);
  84. await NoNextAsync(e);
  85. }
  86. [Fact]
  87. public async Task OrderByDescending2Async()
  88. {
  89. var ex = new Exception("Bang!");
  90. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  91. var ys = xs.OrderByDescending(new Func<int, int>(x => { throw ex; }));
  92. var e = ys.GetAsyncEnumerator();
  93. await AssertThrowsAsync(e.MoveNextAsync(), ex);
  94. }
  95. [Fact]
  96. public async Task OrderByDescending3()
  97. {
  98. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  99. var ys = xs.OrderByDescending(x => x);
  100. await SequenceIdentity(ys);
  101. }
  102. [Fact]
  103. public async Task ThenByDescending2Async()
  104. {
  105. var ex = new Exception("Bang!");
  106. var xs = new[] { 2, 6, 1, 5, 7, 8, 9, 3, 4, 0 }.ToAsyncEnumerable();
  107. var ys = xs.OrderBy(x => x).ThenByDescending(new Func<int, int>(x => { throw ex; }));
  108. var e = ys.GetAsyncEnumerator();
  109. await AssertThrowsAsync(e.MoveNextAsync(), ex);
  110. }
  111. [Fact]
  112. public void OrderByThenBy1()
  113. {
  114. var xs = new[] {
  115. new { Name = "Bart", Age = 27 },
  116. new { Name = "John", Age = 62 },
  117. new { Name = "Eric", Age = 27 },
  118. new { Name = "Lisa", Age = 14 },
  119. new { Name = "Brad", Age = 27 },
  120. new { Name = "Lisa", Age = 23 },
  121. new { Name = "Eric", Age = 42 },
  122. };
  123. var ys = xs.ToAsyncEnumerable();
  124. var ress = xs.OrderBy(x => x.Name).ThenBy(x => x.Age);
  125. var resa = ys.OrderBy(x => x.Name).ThenBy(x => x.Age);
  126. Assert.True(ress.SequenceEqual(resa.ToEnumerable()));
  127. }
  128. [Fact]
  129. public void OrderByThenBy2()
  130. {
  131. var xs = new[] {
  132. new { Name = "Bart", Age = 27 },
  133. new { Name = "John", Age = 62 },
  134. new { Name = "Eric", Age = 27 },
  135. new { Name = "Lisa", Age = 14 },
  136. new { Name = "Brad", Age = 27 },
  137. new { Name = "Lisa", Age = 23 },
  138. new { Name = "Eric", Age = 42 },
  139. };
  140. var ys = xs.ToAsyncEnumerable();
  141. var ress = xs.OrderBy(x => x.Name).ThenByDescending(x => x.Age);
  142. var resa = ys.OrderBy(x => x.Name).ThenByDescending(x => x.Age);
  143. Assert.True(ress.SequenceEqual(resa.ToEnumerable()));
  144. }
  145. [Fact]
  146. public void OrderByThenBy3()
  147. {
  148. var xs = new[] {
  149. new { Name = "Bart", Age = 27 },
  150. new { Name = "John", Age = 62 },
  151. new { Name = "Eric", Age = 27 },
  152. new { Name = "Lisa", Age = 14 },
  153. new { Name = "Brad", Age = 27 },
  154. new { Name = "Lisa", Age = 23 },
  155. new { Name = "Eric", Age = 42 },
  156. };
  157. var ys = xs.ToAsyncEnumerable();
  158. var ress = xs.OrderByDescending(x => x.Name).ThenBy(x => x.Age);
  159. var resa = ys.OrderByDescending(x => x.Name).ThenBy(x => x.Age);
  160. Assert.True(ress.SequenceEqual(resa.ToEnumerable()));
  161. }
  162. [Fact]
  163. public void OrderByThenBy4()
  164. {
  165. var xs = new[] {
  166. new { Name = "Bart", Age = 27 },
  167. new { Name = "John", Age = 62 },
  168. new { Name = "Eric", Age = 27 },
  169. new { Name = "Lisa", Age = 14 },
  170. new { Name = "Brad", Age = 27 },
  171. new { Name = "Lisa", Age = 23 },
  172. new { Name = "Eric", Age = 42 },
  173. };
  174. var ys = xs.ToAsyncEnumerable();
  175. var ress = xs.OrderByDescending(x => x.Name).ThenByDescending(x => x.Age);
  176. var resa = ys.OrderByDescending(x => x.Name).ThenByDescending(x => x.Age);
  177. Assert.True(ress.SequenceEqual(resa.ToEnumerable()));
  178. }
  179. [Fact]
  180. public async Task OrderBy_Optimize_ToArray()
  181. {
  182. foreach (var seed in new[] { 1905, 1948, 1983 })
  183. {
  184. var rand = GetRandom(seed, 10_000);
  185. var randAsync = rand.ToAsyncEnumerable();
  186. var res = rand.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
  187. var resAsync = randAsync.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
  188. var lst = res.ToArray();
  189. var lstAsync = await resAsync.ToArrayAsync();
  190. Assert.True(lst.SequenceEqual(lstAsync));
  191. }
  192. }
  193. [Fact]
  194. public async Task OrderBy_Optimize_ToList()
  195. {
  196. foreach (var seed in new[] { 1905, 1948, 1983 })
  197. {
  198. var rand = GetRandom(seed, 10_000);
  199. var randAsync = rand.ToAsyncEnumerable();
  200. var res = rand.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
  201. var resAsync = randAsync.OrderBy(x => x % 2).ThenBy(x => x % 3).ThenByDescending(x => x % 4);
  202. var lst = res.ToList();
  203. var lstAsync = await resAsync.ToListAsync();
  204. Assert.True(lst.SequenceEqual(lstAsync));
  205. }
  206. }
  207. private static IEnumerable<int> GetRandom(int seed, int count)
  208. {
  209. var rand = new Random(seed);
  210. while (count > 0)
  211. {
  212. yield return rand.Next();
  213. count--;
  214. }
  215. }
  216. }
  217. }