AsyncTests.Single.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  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;
  8. using System.Threading.Tasks;
  9. using Xunit;
  10. namespace Tests
  11. {
  12. public partial class AsyncTests
  13. {
  14. [Fact]
  15. public void MoveNextExtension_Null()
  16. {
  17. var en = default(IAsyncEnumerator<int>);
  18. Assert.ThrowsAsync<ArgumentNullException>(() => en.MoveNextAsync());
  19. }
  20. [Fact]
  21. public void SelectWhere2()
  22. {
  23. var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
  24. var ys = xs.Select(i => i + 2).Where(i => i % 2 == 0);
  25. var e = ys.GetAsyncEnumerator();
  26. HasNext(e, 2);
  27. HasNext(e, 4);
  28. NoNext(e);
  29. }
  30. [Fact]
  31. public void WhereSelect2()
  32. {
  33. var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
  34. var ys = xs.Where(i => i % 2 == 0).Select(i => i + 2);
  35. var e = ys.GetAsyncEnumerator();
  36. HasNext(e, 2);
  37. HasNext(e, 4);
  38. NoNext(e);
  39. }
  40. [Fact]
  41. public void WhereSelect3()
  42. {
  43. var xs = new[] { 0, 1, 2 }.ToAsyncEnumerable();
  44. var ys = xs.Where(i => i % 2 == 0).Select(i => i + 2).Select(i => i + 2);
  45. var e = ys.GetAsyncEnumerator();
  46. HasNext(e, 4);
  47. HasNext(e, 6);
  48. NoNext(e);
  49. }
  50. [Fact]
  51. public void Do_Null()
  52. {
  53. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(null, x => { }));
  54. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), default(Action<int>)));
  55. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(null, x => { }, () => { }));
  56. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), default(Action<int>), () => { }));
  57. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), x => { }, default(Action)));
  58. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(null, x => { }, ex => { }));
  59. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), default(Action<int>), ex => { }));
  60. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), x => { }, default(Action<Exception>)));
  61. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(null, x => { }, ex => { }, () => { }));
  62. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), default(Action<int>), ex => { }, () => { }));
  63. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), x => { }, default(Action<Exception>), () => { }));
  64. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), x => { }, ex => { }, default(Action)));
  65. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(null, new MyObs()));
  66. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Do<int>(AsyncEnumerable.Return(42), default(IObserver<int>)));
  67. }
  68. class MyObs : IObserver<int>
  69. {
  70. public void OnCompleted()
  71. {
  72. throw new NotImplementedException();
  73. }
  74. public void OnError(Exception error)
  75. {
  76. throw new NotImplementedException();
  77. }
  78. public void OnNext(int value)
  79. {
  80. throw new NotImplementedException();
  81. }
  82. }
  83. [Fact]
  84. public void Do1()
  85. {
  86. var sum = 0;
  87. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  88. var ys = xs.Do(x => sum += x);
  89. var e = ys.GetAsyncEnumerator();
  90. HasNext(e, 1);
  91. Assert.Equal(1, sum);
  92. HasNext(e, 2);
  93. Assert.Equal(3, sum);
  94. HasNext(e, 3);
  95. Assert.Equal(6, sum);
  96. HasNext(e, 4);
  97. Assert.Equal(10, sum);
  98. NoNext(e);
  99. }
  100. [Fact]
  101. public void Do2()
  102. {
  103. var ex = new Exception("Bang");
  104. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  105. var ys = xs.Do(x => { throw ex; });
  106. var e = ys.GetAsyncEnumerator();
  107. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  108. }
  109. [Fact]
  110. public void Do3()
  111. {
  112. var sum = 0;
  113. var fail = false;
  114. var done = false;
  115. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  116. var ys = xs.Do(x => sum += x, ex => { fail = true; }, () => { done = true; });
  117. var e = ys.GetAsyncEnumerator();
  118. HasNext(e, 1);
  119. Assert.Equal(1, sum);
  120. HasNext(e, 2);
  121. Assert.Equal(3, sum);
  122. HasNext(e, 3);
  123. Assert.Equal(6, sum);
  124. HasNext(e, 4);
  125. Assert.Equal(10, sum);
  126. NoNext(e);
  127. Assert.False(fail);
  128. Assert.True(done);
  129. }
  130. [Fact]
  131. public void Do4()
  132. {
  133. var sum = 0;
  134. var done = false;
  135. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  136. var ys = xs.Do(x => sum += x, () => { done = true; });
  137. var e = ys.GetAsyncEnumerator();
  138. HasNext(e, 1);
  139. Assert.Equal(1, sum);
  140. HasNext(e, 2);
  141. Assert.Equal(3, sum);
  142. HasNext(e, 3);
  143. Assert.Equal(6, sum);
  144. HasNext(e, 4);
  145. Assert.Equal(10, sum);
  146. NoNext(e);
  147. Assert.True(done);
  148. }
  149. [Fact]
  150. public void Do5()
  151. {
  152. var ex = new Exception("Bang");
  153. var exa = default(Exception);
  154. var done = false;
  155. var hasv = false;
  156. var xs = AsyncEnumerable.Throw<int>(ex);
  157. var ys = xs.Do(x => { hasv = true; }, exx => { exa = exx; }, () => { done = true; });
  158. var e = ys.GetAsyncEnumerator();
  159. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ex_.InnerException == ex);
  160. Assert.False(hasv);
  161. Assert.False(done);
  162. Assert.Same(exa, ex);
  163. }
  164. [Fact]
  165. public void Do6()
  166. {
  167. var ex = new Exception("Bang");
  168. var exa = default(Exception);
  169. var hasv = false;
  170. var xs = AsyncEnumerable.Throw<int>(ex);
  171. var ys = xs.Do(x => { hasv = true; }, exx => { exa = exx; });
  172. var e = ys.GetAsyncEnumerator();
  173. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ex_.InnerException == ex);
  174. Assert.False(hasv);
  175. Assert.Same(exa, ex);
  176. }
  177. [Fact]
  178. public async Task Do7()
  179. {
  180. var sum = 0;
  181. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  182. var ys = xs.Do(x => sum += x);
  183. await SequenceIdentity(ys);
  184. Assert.Equal(20, sum);
  185. }
  186. [Fact]
  187. public async Task ForEachAsync_Null()
  188. {
  189. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(null, x => { }));
  190. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(AsyncEnumerable.Return(42), default(Action<int>)));
  191. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(null, (x, i) => { }));
  192. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(AsyncEnumerable.Return(42), default(Action<int, int>)));
  193. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(null, x => { }, CancellationToken.None));
  194. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(AsyncEnumerable.Return(42), default(Action<int>), CancellationToken.None));
  195. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(null, (x, i) => { }, CancellationToken.None));
  196. await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ForEachAsync<int>(AsyncEnumerable.Return(42), default(Action<int, int>), CancellationToken.None));
  197. }
  198. [Fact]
  199. public void ForEachAsync1()
  200. {
  201. var sum = 0;
  202. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  203. xs.ForEachAsync(x => sum += x).Wait(WaitTimeoutMs);
  204. Assert.Equal(10, sum);
  205. }
  206. [Fact]
  207. public void ForEachAsync2()
  208. {
  209. var sum = 0;
  210. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  211. xs.ForEachAsync((x, i) => sum += x * i).Wait(WaitTimeoutMs);
  212. Assert.Equal(1 * 0 + 2 * 1 + 3 * 2 + 4 * 3, sum);
  213. }
  214. [Fact]
  215. public void ForEachAsync3()
  216. {
  217. var ex = new Exception("Bang");
  218. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  219. AssertThrows<Exception>(() => xs.ForEachAsync(x => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  220. }
  221. [Fact]
  222. public void ForEachAsync4()
  223. {
  224. var ex = new Exception("Bang");
  225. var xs = new[] { 1, 2, 3, 4 }.ToAsyncEnumerable();
  226. AssertThrows<Exception>(() => xs.ForEachAsync((x, i) => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  227. }
  228. [Fact]
  229. public void ForEachAsync5()
  230. {
  231. var ex = new Exception("Bang");
  232. var xs = AsyncEnumerable.Throw<int>(ex);
  233. AssertThrows<Exception>(() => xs.ForEachAsync(x => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  234. }
  235. [Fact]
  236. public void ForEachAsync6()
  237. {
  238. var ex = new Exception("Bang");
  239. var xs = AsyncEnumerable.Throw<int>(ex);
  240. AssertThrows<Exception>(() => xs.ForEachAsync((x, i) => { throw ex; }).Wait(WaitTimeoutMs), ex_ => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  241. }
  242. [Fact]
  243. public void AsAsyncEnumerable_Null()
  244. {
  245. AssertThrows<ArgumentNullException>(() => AsyncEnumerable.AsAsyncEnumerable<int>((IAsyncEnumerable<int>)null));
  246. }
  247. [Fact]
  248. public void AsAsyncEnumerable1()
  249. {
  250. var xs = AsyncEnumerable.Return(42);
  251. var ys = xs.AsAsyncEnumerable();
  252. Assert.NotSame(xs, ys);
  253. var e = xs.GetAsyncEnumerator();
  254. HasNext(e, 42);
  255. NoNext(e);
  256. }
  257. [Fact]
  258. public void RepeatSeq_Null()
  259. {
  260. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>)));
  261. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.Repeat(default(IAsyncEnumerable<int>), 3));
  262. AssertThrows<ArgumentOutOfRangeException>(() => AsyncEnumerableEx.Repeat(AsyncEnumerable.Return(42), -1));
  263. }
  264. [Fact]
  265. public void RepeatSeq1()
  266. {
  267. var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Repeat();
  268. var e = xs.GetAsyncEnumerator();
  269. HasNext(e, 1);
  270. HasNext(e, 2);
  271. HasNext(e, 3);
  272. HasNext(e, 1);
  273. HasNext(e, 2);
  274. HasNext(e, 3);
  275. HasNext(e, 1);
  276. HasNext(e, 2);
  277. HasNext(e, 3);
  278. }
  279. [Fact]
  280. public void RepeatSeq2()
  281. {
  282. var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Repeat(3);
  283. var e = xs.GetAsyncEnumerator();
  284. HasNext(e, 1);
  285. HasNext(e, 2);
  286. HasNext(e, 3);
  287. HasNext(e, 1);
  288. HasNext(e, 2);
  289. HasNext(e, 3);
  290. HasNext(e, 1);
  291. HasNext(e, 2);
  292. HasNext(e, 3);
  293. NoNext(e);
  294. }
  295. [Fact]
  296. public void RepeatSeq3()
  297. {
  298. var i = 0;
  299. var xs = RepeatXs(() => i++).ToAsyncEnumerable().Repeat(3);
  300. var e = xs.GetAsyncEnumerator();
  301. HasNext(e, 1);
  302. HasNext(e, 2);
  303. HasNext(e, 1);
  304. HasNext(e, 2);
  305. HasNext(e, 1);
  306. HasNext(e, 2);
  307. NoNext(e);
  308. Assert.Equal(3, i);
  309. }
  310. [Fact]
  311. public void RepeatSeq0()
  312. {
  313. var i = 0;
  314. var xs = RepeatXs(() => i++).ToAsyncEnumerable().Repeat(0);
  315. var e = xs.GetAsyncEnumerator();
  316. NoNext(e);
  317. }
  318. [Fact]
  319. public async Task RepeatSeq6()
  320. {
  321. var xs = new[] { 1, 2, 3 }.ToAsyncEnumerable().Repeat(3);
  322. await SequenceIdentity(xs);
  323. }
  324. static IEnumerable<int> RepeatXs(Action started)
  325. {
  326. started();
  327. yield return 1;
  328. yield return 2;
  329. }
  330. [Fact]
  331. public void RepeatSeq4()
  332. {
  333. var xs = new FailRepeat().ToAsyncEnumerable().Repeat();
  334. var e = xs.GetAsyncEnumerator();
  335. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is NotImplementedException);
  336. }
  337. [Fact]
  338. public void RepeatSeq5()
  339. {
  340. var xs = new FailRepeat().ToAsyncEnumerable().Repeat(3);
  341. var e = xs.GetAsyncEnumerator();
  342. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() is NotImplementedException);
  343. }
  344. class FailRepeat : IEnumerable<int>
  345. {
  346. public IEnumerator<int> GetEnumerator()
  347. {
  348. throw new NotImplementedException();
  349. }
  350. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  351. {
  352. throw new NotImplementedException();
  353. }
  354. }
  355. [Fact]
  356. public void IgnoreElements_Null()
  357. {
  358. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.IgnoreElements(default(IAsyncEnumerable<int>)));
  359. }
  360. [Fact]
  361. public void IgnoreElements1()
  362. {
  363. var xs = AsyncEnumerable.Empty<int>().IgnoreElements();
  364. var e = xs.GetAsyncEnumerator();
  365. NoNext(e);
  366. AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
  367. }
  368. [Fact]
  369. public void IgnoreElements2()
  370. {
  371. var xs = AsyncEnumerable.Return(42).IgnoreElements();
  372. var e = xs.GetAsyncEnumerator();
  373. NoNext(e);
  374. AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
  375. }
  376. [Fact]
  377. public void IgnoreElements3()
  378. {
  379. var xs = AsyncEnumerable.Range(0, 10).IgnoreElements();
  380. var e = xs.GetAsyncEnumerator();
  381. NoNext(e);
  382. AssertThrows<InvalidOperationException>(() => { var ignored = e.Current; });
  383. }
  384. [Fact]
  385. public void IgnoreElements4()
  386. {
  387. var ex = new Exception("Bang!");
  388. var xs = AsyncEnumerable.Throw<int>(ex).IgnoreElements();
  389. var e = xs.GetAsyncEnumerator();
  390. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  391. }
  392. [Fact]
  393. public async Task IgnoreElements5()
  394. {
  395. var xs = AsyncEnumerable.Range(0, 10).IgnoreElements();
  396. await SequenceIdentity(xs);
  397. }
  398. [Fact]
  399. public void StartWith_Null()
  400. {
  401. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(default(IAsyncEnumerable<int>), new[] { 1 }));
  402. AssertThrows<ArgumentNullException>(() => AsyncEnumerableEx.StartWith(AsyncEnumerable.Return(42), null));
  403. }
  404. [Fact]
  405. public void StartWith1()
  406. {
  407. var xs = AsyncEnumerable.Empty<int>().StartWith(1, 2);
  408. var e = xs.GetAsyncEnumerator();
  409. HasNext(e, 1);
  410. HasNext(e, 2);
  411. NoNext(e);
  412. }
  413. [Fact]
  414. public void StartWith2()
  415. {
  416. var xs = AsyncEnumerable.Return<int>(0).StartWith(1, 2);
  417. var e = xs.GetAsyncEnumerator();
  418. HasNext(e, 1);
  419. HasNext(e, 2);
  420. HasNext(e, 0);
  421. NoNext(e);
  422. }
  423. [Fact]
  424. public void StartWith3()
  425. {
  426. var ex = new Exception("Bang!");
  427. var xs = AsyncEnumerable.Throw<int>(ex).StartWith(1, 2);
  428. var e = xs.GetAsyncEnumerator();
  429. HasNext(e, 1);
  430. HasNext(e, 2);
  431. AssertThrows(() => e.MoveNextAsync().Wait(WaitTimeoutMs), (Exception ex_) => ((AggregateException)ex_).Flatten().InnerExceptions.Single() == ex);
  432. }
  433. }
  434. }