AsyncTests.Creation.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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.Text;
  8. using Xunit;
  9. using System.Threading.Tasks;
  10. using System.Threading;
  11. namespace Tests
  12. {
  13. public partial class AsyncTests
  14. {
  15. [Fact]
  16. public void Return()
  17. {
  18. var xs = AsyncEnumerable.Return(42);
  19. HasNext(xs.GetEnumerator(), 42);
  20. }
  21. [Fact]
  22. public void Never()
  23. {
  24. var xs = AsyncEnumerable.Never<int>();
  25. var e = xs.GetEnumerator();
  26. Assert.False(e.MoveNext().IsCompleted); // Very rudimentary check
  27. AssertThrows<InvalidOperationException>(() => Nop(e.Current));
  28. e.Dispose();
  29. }
  30. [Fact]
  31. public void Empty1()
  32. {
  33. var xs = AsyncEnumerable.Empty<int>();
  34. NoNext(xs.GetEnumerator());
  35. }
  36. [Fact]
  37. public void Empty2()
  38. {
  39. var xs = AsyncEnumerable.Empty<int>();
  40. var e = xs.GetEnumerator();
  41. Assert.False(e.MoveNext().Result);
  42. AssertThrows<InvalidOperationException>(() => Nop(e.Current));
  43. }
  44. [Fact]
  45. public void Throw_Null()
  46. {
  47. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Throw<int>(null));
  48. }
  49. [Fact]
  50. public void Throw()
  51. {
  52. var ex = new Exception("Bang");
  53. var xs = AsyncEnumerable.Throw<int>(ex);
  54. var e = xs.GetEnumerator();
  55. AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).InnerExceptions.Single() == ex);
  56. AssertThrows<InvalidOperationException>(() => Nop(e.Current));
  57. }
  58. private void Nop(object o)
  59. {
  60. }
  61. [Fact]
  62. public void Range_Null()
  63. {
  64. AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerable.Range(0, -1));
  65. }
  66. [Fact]
  67. public void Range1()
  68. {
  69. var xs = AsyncEnumerable.Range(2, 5);
  70. var e = xs.GetEnumerator();
  71. HasNext(e, 2);
  72. HasNext(e, 3);
  73. HasNext(e, 4);
  74. HasNext(e, 5);
  75. HasNext(e, 6);
  76. NoNext(e);
  77. }
  78. [Fact]
  79. public void Range2()
  80. {
  81. var xs = AsyncEnumerable.Range(2, 0);
  82. var e = xs.GetEnumerator();
  83. NoNext(e);
  84. }
  85. [Fact]
  86. public void Repeat_Null()
  87. {
  88. AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerable.Repeat(0, -1));
  89. }
  90. [Fact]
  91. public void Repeat1()
  92. {
  93. var xs = AsyncEnumerable.Repeat(2, 5);
  94. var e = xs.GetEnumerator();
  95. HasNext(e, 2);
  96. HasNext(e, 2);
  97. HasNext(e, 2);
  98. HasNext(e, 2);
  99. HasNext(e, 2);
  100. NoNext(e);
  101. }
  102. [Fact]
  103. public void Repeat2()
  104. {
  105. var xs = AsyncEnumerable.Repeat(2, 0);
  106. var e = xs.GetEnumerator();
  107. NoNext(e);
  108. }
  109. [Fact]
  110. public void Repeat3()
  111. {
  112. var xs = AsyncEnumerable.Repeat(2);
  113. var e = xs.GetEnumerator();
  114. HasNext(e, 2);
  115. HasNext(e, 2);
  116. HasNext(e, 2);
  117. HasNext(e, 2);
  118. HasNext(e, 2);
  119. e.Dispose();
  120. }
  121. [Fact]
  122. public void Defer_Null()
  123. {
  124. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Defer<int>(null));
  125. }
  126. [Fact]
  127. public void Defer1()
  128. {
  129. var x = 0;
  130. var xs = AsyncEnumerable.Defer<int>(() => new[] { x }.ToAsyncEnumerable());
  131. {
  132. var e = xs.GetEnumerator();
  133. HasNext(e, 0);
  134. NoNext(e);
  135. }
  136. {
  137. x++;
  138. var e = xs.GetEnumerator();
  139. HasNext(e, 1);
  140. NoNext(e);
  141. }
  142. }
  143. [Fact]
  144. public void Generate_Null()
  145. {
  146. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Generate<int, int>(0, null, x => x, x => x));
  147. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Generate<int, int>(0, x => true, null, x => x));
  148. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Generate<int, int>(0, x => true, x => x, null));
  149. }
  150. [Fact]
  151. public void Generate1()
  152. {
  153. var xs = AsyncEnumerable.Generate(0, x => x < 5, x => x + 1, x => x * x);
  154. var e = xs.GetEnumerator();
  155. HasNext(e, 0);
  156. HasNext(e, 1);
  157. HasNext(e, 4);
  158. HasNext(e, 9);
  159. HasNext(e, 16);
  160. NoNext(e);
  161. e.Dispose();
  162. }
  163. [Fact]
  164. public void Generate2()
  165. {
  166. var ex = new Exception("Bang!");
  167. var xs = AsyncEnumerable.Generate(0, x => { throw ex; }, x => x + 1, x => x * x);
  168. var e = xs.GetEnumerator();
  169. AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).InnerExceptions.Single() == ex);
  170. }
  171. [Fact]
  172. public void Generate3()
  173. {
  174. var ex = new Exception("Bang!");
  175. var xs = AsyncEnumerable.Generate(0, x => true, x => x + 1, x => { if (x == 1) throw ex; return x * x; });
  176. var e = xs.GetEnumerator();
  177. HasNext(e, 0);
  178. AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).InnerExceptions.Single() == ex);
  179. }
  180. [Fact]
  181. public void Generate4()
  182. {
  183. var ex = new Exception("Bang!");
  184. var xs = AsyncEnumerable.Generate(0, x => true, x => { throw ex; }, x => x * x);
  185. var e = xs.GetEnumerator();
  186. HasNext(e, 0);
  187. AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).InnerExceptions.Single() == ex);
  188. }
  189. [Fact]
  190. public void Using_Null()
  191. {
  192. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Using<int, IDisposable>(null, _ => null));
  193. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.Using<int, IDisposable>(() => new MyD(null), null));
  194. }
  195. [Fact]
  196. public void Using1()
  197. {
  198. var i = 0;
  199. var d = 0;
  200. var xs = AsyncEnumerable.Using(
  201. () =>
  202. {
  203. i++;
  204. return new MyD(() => { d++; });
  205. },
  206. _ => AsyncEnumerable.Return(42)
  207. );
  208. Assert.Equal(0, i);
  209. var e = xs.GetEnumerator();
  210. Assert.Equal(1, i);
  211. }
  212. [Fact]
  213. public void Using2()
  214. {
  215. var i = 0;
  216. var d = 0;
  217. var xs = AsyncEnumerable.Using(
  218. () =>
  219. {
  220. i++;
  221. return new MyD(() => { d++; });
  222. },
  223. _ => AsyncEnumerable.Return(42)
  224. );
  225. Assert.Equal(0, i);
  226. var e = xs.GetEnumerator();
  227. Assert.Equal(1, i);
  228. e.Dispose();
  229. Assert.Equal(1, d);
  230. }
  231. [Fact]
  232. public void Using3()
  233. {
  234. var ex = new Exception("Bang!");
  235. var i = 0;
  236. var d = 0;
  237. var xs = AsyncEnumerable.Using<int, MyD>(
  238. () =>
  239. {
  240. i++;
  241. return new MyD(() => { d++; });
  242. },
  243. _ => { throw ex; }
  244. );
  245. Assert.Equal(0, i);
  246. AssertThrows<Exception>(() => xs.GetEnumerator(), ex_ => ex_ == ex);
  247. Assert.Equal(1, d);
  248. }
  249. [Fact]
  250. public void Using4()
  251. {
  252. var i = 0;
  253. var disposed = new TaskCompletionSource<bool>();
  254. var xs = AsyncEnumerable.Using(
  255. () =>
  256. {
  257. i++;
  258. return new MyD(() => { disposed.TrySetResult(true); });
  259. },
  260. _ => AsyncEnumerable.Return(42)
  261. );
  262. Assert.Equal(0, i);
  263. var e = xs.GetEnumerator();
  264. Assert.Equal(1, i);
  265. HasNext(e, 42);
  266. NoNext(e);
  267. Assert.True(disposed.Task.Result);
  268. }
  269. [Fact]
  270. public void Using5()
  271. {
  272. var ex = new Exception("Bang!");
  273. var i = 0;
  274. var disposed = new TaskCompletionSource<bool>();
  275. var xs = AsyncEnumerable.Using(
  276. () =>
  277. {
  278. i++;
  279. return new MyD(() => { disposed.TrySetResult(true); });
  280. },
  281. _ => AsyncEnumerable.Throw<int>(ex)
  282. );
  283. Assert.Equal(0, i);
  284. var e = xs.GetEnumerator();
  285. Assert.Equal(1, i);
  286. AssertThrows<Exception>(() => e.MoveNext().Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  287. Assert.True(disposed.Task.Result);
  288. }
  289. [Fact]
  290. public async Task Using6()
  291. {
  292. var i = 0;
  293. var disposed = new TaskCompletionSource<bool>();
  294. var xs = AsyncEnumerable.Using(
  295. () =>
  296. {
  297. i++;
  298. return new MyD(() => { disposed.TrySetResult(true); });
  299. },
  300. _ => new CancellationTestAsyncEnumerable(2) // need to use this to verify we actually cancel
  301. );
  302. Assert.Equal(0, i);
  303. var e = xs.GetEnumerator();
  304. Assert.Equal(1, i);
  305. HasNext(e, 0);
  306. HasNext(e, 1);
  307. var cts = new CancellationTokenSource();
  308. var t = e.MoveNext(cts.Token);
  309. cts.Cancel();
  310. try
  311. {
  312. t.Wait(WaitTimeoutMs);
  313. }
  314. catch (AggregateException ex)
  315. {
  316. ex.Flatten().Handle(inner => inner is TaskCanceledException);
  317. }
  318. Assert.True(disposed.Task.IsCompleted);
  319. Assert.True(await disposed.Task);
  320. }
  321. class MyD : IDisposable
  322. {
  323. private readonly Action _dispose;
  324. public MyD(Action dispose)
  325. {
  326. _dispose = dispose;
  327. }
  328. public void Dispose()
  329. {
  330. _dispose();
  331. }
  332. }
  333. }
  334. }