Single.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using Xunit;
  9. namespace Tests
  10. {
  11. public class Single : AsyncEnumerableTests
  12. {
  13. [Fact]
  14. public async Task SingleAsync_Null()
  15. {
  16. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync<int>(default).AsTask());
  17. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync<int>(default, CancellationToken.None).AsTask());
  18. }
  19. [Fact]
  20. public async Task SingleAsync_Empty()
  21. {
  22. var res = AsyncEnumerable.Empty<int>().SingleAsync();
  23. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  24. }
  25. [Fact]
  26. public async Task SingleAsync_Empty_IList()
  27. {
  28. var res = Array.Empty<int>().ToAsyncEnumerable().SingleAsync();
  29. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  30. }
  31. [Fact]
  32. public async Task SingleAsync_Single()
  33. {
  34. var res = Return42.SingleAsync();
  35. Assert.Equal(42, await res);
  36. }
  37. [Fact]
  38. public async Task SingleAsync_Simple()
  39. {
  40. var res = new[] { 1, 2, 3, 4, 5 }.ToAsyncEnumerable().Where(x => x == 4).SingleAsync();
  41. Assert.Equal(4, await res);
  42. }
  43. [Fact]
  44. public async Task SingleAsync_Throws_Source()
  45. {
  46. var ex = new Exception("Bang!");
  47. var res = Throw<int>(ex).SingleAsync();
  48. await AssertThrowsAsync(res, ex);
  49. }
  50. [Fact]
  51. public async Task SingleAsync_Throw_MoreThanOne_IList()
  52. {
  53. var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().SingleAsync();
  54. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  55. }
  56. [Fact]
  57. public async Task SingleAsync_Throw_MoreThanOne()
  58. {
  59. var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().Select(x => x).SingleAsync();
  60. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  61. }
  62. [Fact]
  63. public async Task SingleAsync_Predicate_Null()
  64. {
  65. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync<int>(default, x => true).AsTask());
  66. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync(Return42, default(Func<int, bool>)).AsTask());
  67. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync<int>(default, x => true, CancellationToken.None).AsTask());
  68. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAsync(Return42, default, CancellationToken.None).AsTask());
  69. }
  70. [Fact]
  71. public async Task SingleAsync_Predicate_Empty()
  72. {
  73. var res = AsyncEnumerable.Empty<int>().SingleAsync(x => true);
  74. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  75. }
  76. [Fact]
  77. public async Task SingleAsync_Predicate_NoMatch()
  78. {
  79. var res = Return42.SingleAsync(x => x % 2 != 0);
  80. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  81. }
  82. [Fact]
  83. public async Task SingleAsync_Predicate_Simple()
  84. {
  85. var res = Return42.SingleAsync(x => x % 2 == 0);
  86. Assert.Equal(42, await res);
  87. }
  88. [Fact]
  89. public async Task SingleAsync_Predicate_Throws()
  90. {
  91. var ex = new Exception("Bang!");
  92. var res = Throw<int>(ex).SingleAsync(x => true);
  93. await AssertThrowsAsync(res, ex);
  94. }
  95. [Fact]
  96. public async Task SingleAsync_Predicate_OneMatch()
  97. {
  98. var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().SingleAsync(x => x % 2 != 0);
  99. Assert.Equal(45, await res);
  100. }
  101. [Fact]
  102. public async Task SingleAsync_Predicate_Throw_MoreThanOne()
  103. {
  104. var res = new[] { 42, 23, 45, 90 }.ToAsyncEnumerable().SingleAsync(x => x % 2 != 0);
  105. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  106. }
  107. [Fact]
  108. public async Task SingleAwaitAsync_Predicate_Null()
  109. {
  110. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitAsync<int>(default, x => new ValueTask<bool>(true)).AsTask());
  111. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitAsync(Return42, default).AsTask());
  112. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitAsync<int>(default, x => new ValueTask<bool>(true), CancellationToken.None).AsTask());
  113. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitAsync(Return42, default, CancellationToken.None).AsTask());
  114. }
  115. [Fact]
  116. public async Task SingleAwaitAsync_Predicate_Empty()
  117. {
  118. var res = AsyncEnumerable.Empty<int>().SingleAwaitAsync(x => new ValueTask<bool>(true));
  119. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  120. }
  121. [Fact]
  122. public async Task SingleAwaitAsync_Predicate_NoMatch()
  123. {
  124. var res = Return42.SingleAwaitAsync(x => new ValueTask<bool>(x % 2 != 0));
  125. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  126. }
  127. [Fact]
  128. public async Task SingleAwaitAsync_Predicate_Simple()
  129. {
  130. var res = Return42.SingleAwaitAsync(x => new ValueTask<bool>(x % 2 == 0));
  131. Assert.Equal(42, await res);
  132. }
  133. [Fact]
  134. public async Task SingleAwaitAsync_Predicate_Throws()
  135. {
  136. var ex = new Exception("Bang!");
  137. var res = Throw<int>(ex).SingleAwaitAsync(x => new ValueTask<bool>(true));
  138. await AssertThrowsAsync(res, ex);
  139. }
  140. [Fact]
  141. public async Task SingleAwaitAsync_Predicate_OneMatch()
  142. {
  143. var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().SingleAwaitAsync(x => new ValueTask<bool>(x % 2 != 0));
  144. Assert.Equal(45, await res);
  145. }
  146. [Fact]
  147. public async Task SingleAwaitAsync_Predicate_Throw_MoreThanOne()
  148. {
  149. var res = new[] { 42, 23, 45, 90 }.ToAsyncEnumerable().SingleAwaitAsync(x => new ValueTask<bool>(x % 2 != 0));
  150. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  151. }
  152. #if !NO_DEEP_CANCELLATION
  153. [Fact]
  154. public async Task SingleAwaitWithCancellationAsync_Predicate_Null()
  155. {
  156. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitWithCancellationAsync<int>(default, (x, ct) => new ValueTask<bool>(true), CancellationToken.None).AsTask());
  157. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.SingleAwaitWithCancellationAsync(Return42, default, CancellationToken.None).AsTask());
  158. }
  159. [Fact]
  160. public async Task SingleAwaitWithCancellationAsync_Predicate_Empty()
  161. {
  162. var res = AsyncEnumerable.Empty<int>().SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(true));
  163. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  164. }
  165. [Fact]
  166. public async Task SingleAwaitWithCancellationAsync_Predicate_NoMatch()
  167. {
  168. var res = Return42.SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(x % 2 != 0));
  169. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  170. }
  171. [Fact]
  172. public async Task SingleAwaitWithCancellationAsync_Predicate_Simple()
  173. {
  174. var res = Return42.SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(x % 2 == 0));
  175. Assert.Equal(42, await res);
  176. }
  177. [Fact]
  178. public async Task SingleAwaitWithCancellationAsync_Predicate_Throws()
  179. {
  180. var ex = new Exception("Bang!");
  181. var res = Throw<int>(ex).SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(true));
  182. await AssertThrowsAsync(res, ex);
  183. }
  184. [Fact]
  185. public async Task SingleAwaitWithCancellationAsync_Predicate_OneMatch()
  186. {
  187. var res = new[] { 42, 45, 90 }.ToAsyncEnumerable().SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(x % 2 != 0));
  188. Assert.Equal(45, await res);
  189. }
  190. [Fact]
  191. public async Task SingleAwaitWithCancellationAsync_Predicate_Throw_MoreThanOne()
  192. {
  193. var res = new[] { 42, 23, 45, 90 }.ToAsyncEnumerable().SingleAwaitWithCancellationAsync((x, ct) => new ValueTask<bool>(x % 2 != 0));
  194. await AssertThrowsAsync<InvalidOperationException>(res.AsTask());
  195. }
  196. #endif
  197. }
  198. }