Tests.Buffering.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  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.Text;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using Xunit;
  9. using System.Collections;
  10. namespace Tests
  11. {
  12. public partial class Tests
  13. {
  14. [Fact]
  15. public void Share_Arguments()
  16. {
  17. AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int>(null));
  18. }
  19. [Fact]
  20. public void Share1()
  21. {
  22. var rng = Enumerable.Range(0, 5).Share();
  23. var e1 = rng.GetEnumerator();
  24. HasNext(e1, 0);
  25. HasNext(e1, 1);
  26. HasNext(e1, 2);
  27. HasNext(e1, 3);
  28. HasNext(e1, 4);
  29. NoNext(e1);
  30. }
  31. [Fact]
  32. public void Share2()
  33. {
  34. var rng = Enumerable.Range(0, 5).Share();
  35. var e1 = rng.GetEnumerator();
  36. var e2 = rng.GetEnumerator();
  37. HasNext(e1, 0);
  38. HasNext(e2, 1);
  39. HasNext(e1, 2);
  40. HasNext(e2, 3);
  41. HasNext(e1, 4);
  42. NoNext(e2);
  43. NoNext(e1);
  44. }
  45. [Fact]
  46. public void Share3()
  47. {
  48. var rng = Enumerable.Range(0, 5).Share();
  49. var e1 = rng.GetEnumerator();
  50. HasNext(e1, 0);
  51. HasNext(e1, 1);
  52. HasNext(e1, 2);
  53. var e2 = rng.GetEnumerator();
  54. HasNext(e2, 3);
  55. HasNext(e2, 4);
  56. NoNext(e2);
  57. NoNext(e1);
  58. }
  59. //[Fact]
  60. public void Share4()
  61. {
  62. var rng = Enumerable.Range(0, 5).Share();
  63. var e1 = rng.GetEnumerator();
  64. HasNext(e1, 0);
  65. HasNext(e1, 1);
  66. HasNext(e1, 2);
  67. e1.Dispose();
  68. Assert.False(e1.MoveNext());
  69. }
  70. [Fact]
  71. public void Share5()
  72. {
  73. var rng = Enumerable.Range(0, 5).Share();
  74. var e1 = rng.GetEnumerator();
  75. HasNext(e1, 0);
  76. HasNext(e1, 1);
  77. HasNext(e1, 2);
  78. rng.Dispose();
  79. AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
  80. AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
  81. AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
  82. }
  83. [Fact]
  84. public void Share6()
  85. {
  86. var rng = Enumerable.Range(0, 5).Share();
  87. var e1 = ((IEnumerable)rng).GetEnumerator();
  88. Assert.True(e1.MoveNext());
  89. Assert.Equal(0, (int)e1.Current);
  90. }
  91. [Fact]
  92. public void Publish_Arguments()
  93. {
  94. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int>(null));
  95. }
  96. [Fact]
  97. public void Publish0()
  98. {
  99. var n = 0;
  100. var rng = Tick(i => n += i).Publish();
  101. var e1 = rng.GetEnumerator();
  102. var e2 = rng.GetEnumerator();
  103. HasNext(e1, 0);
  104. Assert.Equal(0, n);
  105. HasNext(e1, 1);
  106. Assert.Equal(1, n);
  107. HasNext(e1, 2);
  108. Assert.Equal(3, n);
  109. HasNext(e2, 0);
  110. Assert.Equal(3, n);
  111. HasNext(e1, 3);
  112. Assert.Equal(6, n);
  113. HasNext(e2, 1);
  114. Assert.Equal(6, n);
  115. HasNext(e2, 2);
  116. Assert.Equal(6, n);
  117. HasNext(e2, 3);
  118. Assert.Equal(6, n);
  119. HasNext(e2, 4);
  120. Assert.Equal(10, n);
  121. HasNext(e1, 4);
  122. Assert.Equal(10, n);
  123. }
  124. static IEnumerable<int> Tick(Action<int> t)
  125. {
  126. var i = 0;
  127. while (true)
  128. {
  129. t(i);
  130. yield return i++;
  131. }
  132. }
  133. [Fact]
  134. public void Publish1()
  135. {
  136. var rng = Enumerable.Range(0, 5).Publish();
  137. var e1 = rng.GetEnumerator();
  138. HasNext(e1, 0);
  139. HasNext(e1, 1);
  140. HasNext(e1, 2);
  141. HasNext(e1, 3);
  142. HasNext(e1, 4);
  143. NoNext(e1);
  144. }
  145. [Fact]
  146. public void Publish2()
  147. {
  148. var rng = Enumerable.Range(0, 5).Publish();
  149. var e1 = rng.GetEnumerator();
  150. var e2 = rng.GetEnumerator();
  151. HasNext(e1, 0);
  152. HasNext(e2, 0);
  153. HasNext(e1, 1);
  154. HasNext(e2, 1);
  155. HasNext(e1, 2);
  156. HasNext(e2, 2);
  157. HasNext(e1, 3);
  158. HasNext(e2, 3);
  159. HasNext(e1, 4);
  160. HasNext(e2, 4);
  161. NoNext(e1);
  162. NoNext(e2);
  163. }
  164. [Fact]
  165. public void Publish3()
  166. {
  167. var rng = Enumerable.Range(0, 5).Publish();
  168. var e1 = rng.GetEnumerator();
  169. var e2 = rng.GetEnumerator();
  170. HasNext(e1, 0);
  171. HasNext(e1, 1);
  172. HasNext(e1, 2);
  173. HasNext(e1, 3);
  174. HasNext(e1, 4);
  175. HasNext(e2, 0);
  176. HasNext(e2, 1);
  177. HasNext(e2, 2);
  178. HasNext(e2, 3);
  179. HasNext(e2, 4);
  180. NoNext(e1);
  181. NoNext(e2);
  182. }
  183. [Fact]
  184. public void Publish4()
  185. {
  186. var rng = Enumerable.Range(0, 5).Publish();
  187. var e1 = rng.GetEnumerator();
  188. HasNext(e1, 0);
  189. HasNext(e1, 1);
  190. HasNext(e1, 2);
  191. var e2 = rng.GetEnumerator();
  192. HasNext(e1, 3);
  193. HasNext(e1, 4);
  194. HasNext(e2, 3);
  195. HasNext(e2, 4);
  196. NoNext(e1);
  197. NoNext(e2);
  198. }
  199. [Fact]
  200. public void Publish5()
  201. {
  202. var rng = Enumerable.Range(0, 5).Publish();
  203. var e1 = rng.GetEnumerator();
  204. HasNext(e1, 0);
  205. HasNext(e1, 1);
  206. HasNext(e1, 2);
  207. e1.Dispose();
  208. var e2 = rng.GetEnumerator();
  209. HasNext(e2, 3);
  210. HasNext(e2, 4);
  211. NoNext(e2);
  212. }
  213. [Fact]
  214. public void Publish6()
  215. {
  216. var ex = new MyException();
  217. var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Publish();
  218. var e1 = rng.GetEnumerator();
  219. var e2 = rng.GetEnumerator();
  220. HasNext(e1, 0);
  221. HasNext(e1, 1);
  222. AssertThrows<MyException>(() => e1.MoveNext());
  223. HasNext(e2, 0);
  224. HasNext(e2, 1);
  225. AssertThrows<MyException>(() => e2.MoveNext());
  226. }
  227. class MyException : Exception
  228. {
  229. }
  230. [Fact]
  231. public void Publish7()
  232. {
  233. var rng = Enumerable.Range(0, 5).Publish();
  234. var e1 = rng.GetEnumerator();
  235. HasNext(e1, 0);
  236. HasNext(e1, 1);
  237. HasNext(e1, 2);
  238. var e2 = rng.GetEnumerator();
  239. HasNext(e2, 3);
  240. HasNext(e2, 4);
  241. NoNext(e2);
  242. HasNext(e1, 3);
  243. HasNext(e1, 4);
  244. NoNext(e2);
  245. var e3 = rng.GetEnumerator();
  246. NoNext(e3);
  247. }
  248. [Fact]
  249. public void Publish8()
  250. {
  251. var rng = Enumerable.Range(0, 5).Publish();
  252. var e1 = rng.GetEnumerator();
  253. HasNext(e1, 0);
  254. HasNext(e1, 1);
  255. HasNext(e1, 2);
  256. rng.Dispose();
  257. AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
  258. AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
  259. AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
  260. }
  261. [Fact]
  262. public void Publish9()
  263. {
  264. var rng = Enumerable.Range(0, 5).Publish();
  265. var e1 = ((IEnumerable)rng).GetEnumerator();
  266. Assert.True(e1.MoveNext());
  267. Assert.Equal(0, (int)e1.Current);
  268. }
  269. [Fact]
  270. public void Publish10()
  271. {
  272. var rnd = Rand().Take(1000).Publish();
  273. Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
  274. }
  275. [Fact]
  276. public void Memoize_Arguments()
  277. {
  278. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null));
  279. }
  280. [Fact]
  281. public void MemoizeLimited_Arguments()
  282. {
  283. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null, 2));
  284. AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, 0));
  285. AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, -1));
  286. }
  287. [Fact]
  288. public void Memoize0()
  289. {
  290. var n = 0;
  291. var rng = Tick(i => n += i).Memoize();
  292. var e1 = rng.GetEnumerator();
  293. var e2 = rng.GetEnumerator();
  294. HasNext(e1, 0);
  295. Assert.Equal(0, n);
  296. HasNext(e1, 1);
  297. Assert.Equal(1, n);
  298. HasNext(e1, 2);
  299. Assert.Equal(3, n);
  300. HasNext(e2, 0);
  301. Assert.Equal(3, n);
  302. HasNext(e1, 3);
  303. Assert.Equal(6, n);
  304. HasNext(e2, 1);
  305. Assert.Equal(6, n);
  306. HasNext(e2, 2);
  307. Assert.Equal(6, n);
  308. HasNext(e2, 3);
  309. Assert.Equal(6, n);
  310. HasNext(e2, 4);
  311. Assert.Equal(10, n);
  312. HasNext(e1, 4);
  313. Assert.Equal(10, n);
  314. }
  315. [Fact]
  316. public void Publish11()
  317. {
  318. var rng = Enumerable.Range(0, 5).Publish();
  319. var e1 = rng.GetEnumerator();
  320. var e2 = rng.GetEnumerator();
  321. HasNext(e1, 0);
  322. HasNext(e1, 1);
  323. HasNext(e1, 2);
  324. e1.Dispose();
  325. HasNext(e2, 0);
  326. HasNext(e2, 1);
  327. e2.Dispose();
  328. var e3 = rng.GetEnumerator();
  329. HasNext(e3, 3);
  330. HasNext(e3, 4);
  331. NoNext(e3);
  332. }
  333. [Fact]
  334. public void Memoize1()
  335. {
  336. var rng = Enumerable.Range(0, 5).Memoize();
  337. var e1 = rng.GetEnumerator();
  338. HasNext(e1, 0);
  339. HasNext(e1, 1);
  340. HasNext(e1, 2);
  341. HasNext(e1, 3);
  342. HasNext(e1, 4);
  343. NoNext(e1);
  344. }
  345. [Fact]
  346. public void Memoize2()
  347. {
  348. var rng = Enumerable.Range(0, 5).Memoize();
  349. var e1 = rng.GetEnumerator();
  350. HasNext(e1, 0);
  351. HasNext(e1, 1);
  352. HasNext(e1, 2);
  353. HasNext(e1, 3);
  354. HasNext(e1, 4);
  355. NoNext(e1);
  356. var e2 = rng.GetEnumerator();
  357. HasNext(e2, 0);
  358. HasNext(e2, 1);
  359. HasNext(e2, 2);
  360. HasNext(e2, 3);
  361. HasNext(e2, 4);
  362. NoNext(e2);
  363. }
  364. [Fact]
  365. public void Memoize3()
  366. {
  367. var rng = Enumerable.Range(0, 5).Memoize();
  368. var e1 = rng.GetEnumerator();
  369. HasNext(e1, 0);
  370. HasNext(e1, 1);
  371. HasNext(e1, 2);
  372. var e2 = rng.GetEnumerator();
  373. HasNext(e1, 3);
  374. HasNext(e2, 0);
  375. HasNext(e2, 1);
  376. HasNext(e1, 4);
  377. HasNext(e2, 2);
  378. NoNext(e1);
  379. HasNext(e2, 3);
  380. HasNext(e2, 4);
  381. NoNext(e2);
  382. }
  383. [Fact]
  384. public void Memoize4()
  385. {
  386. var rng = Enumerable.Range(0, 5).Memoize(2);
  387. var e1 = rng.GetEnumerator();
  388. HasNext(e1, 0);
  389. HasNext(e1, 1);
  390. HasNext(e1, 2);
  391. var e2 = rng.GetEnumerator();
  392. HasNext(e2, 0);
  393. HasNext(e2, 1);
  394. HasNext(e2, 2);
  395. var e3 = rng.GetEnumerator();
  396. AssertThrows<InvalidOperationException>(() => e3.MoveNext());
  397. }
  398. [Fact]
  399. public void Memoize6()
  400. {
  401. var ex = new MyException();
  402. var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Memoize();
  403. var e1 = rng.GetEnumerator();
  404. var e2 = rng.GetEnumerator();
  405. HasNext(e1, 0);
  406. HasNext(e1, 1);
  407. AssertThrows<MyException>(() => e1.MoveNext());
  408. HasNext(e2, 0);
  409. HasNext(e2, 1);
  410. AssertThrows<MyException>(() => e2.MoveNext());
  411. }
  412. [Fact]
  413. public void Memoize7()
  414. {
  415. var rng = Enumerable.Range(0, 5).Memoize();
  416. var e1 = rng.GetEnumerator();
  417. HasNext(e1, 0);
  418. HasNext(e1, 1);
  419. HasNext(e1, 2);
  420. e1.Dispose();
  421. var e2 = rng.GetEnumerator();
  422. HasNext(e2, 0);
  423. HasNext(e2, 1);
  424. e2.Dispose();
  425. var e3 = rng.GetEnumerator();
  426. HasNext(e3, 0);
  427. HasNext(e3, 1);
  428. HasNext(e3, 2);
  429. HasNext(e3, 3);
  430. HasNext(e3, 4);
  431. NoNext(e3);
  432. }
  433. [Fact]
  434. public void Memoize8()
  435. {
  436. var rng = Enumerable.Range(0, 5).Memoize();
  437. var e1 = rng.GetEnumerator();
  438. HasNext(e1, 0);
  439. HasNext(e1, 1);
  440. HasNext(e1, 2);
  441. rng.Dispose();
  442. AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
  443. AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
  444. AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
  445. }
  446. [Fact]
  447. public void Memoize9()
  448. {
  449. var rng = Enumerable.Range(0, 5).Memoize();
  450. var e1 = ((IEnumerable)rng).GetEnumerator();
  451. Assert.True(e1.MoveNext());
  452. Assert.Equal(0, (int)e1.Current);
  453. }
  454. [Fact]
  455. public void Memoize10()
  456. {
  457. var rnd = Rand().Take(1000).Memoize();
  458. Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
  459. }
  460. static Random s_rand = new Random();
  461. static IEnumerable<int> Rand()
  462. {
  463. while (true)
  464. yield return s_rand.Next();
  465. }
  466. [Fact]
  467. public void ShareLambda_Arguments()
  468. {
  469. AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(null, xs => xs));
  470. AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(new[] { 1 }, null));
  471. }
  472. [Fact]
  473. public void ShareLambda()
  474. {
  475. var n = 0;
  476. var res = Enumerable.Range(0, 10).Do(_ => n++).Share(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
  477. Assert.True(res.SequenceEqual(new[] { 0 + 1, 2 + 3, 4 + 5, 6 + 7 }));
  478. Assert.Equal(8, n);
  479. }
  480. [Fact]
  481. public void PublishLambda_Arguments()
  482. {
  483. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(null, xs => xs));
  484. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(new[] { 1 }, null));
  485. }
  486. [Fact]
  487. public void PublishLambda()
  488. {
  489. var n = 0;
  490. var res = Enumerable.Range(0, 10).Do(_ => n++).Publish(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
  491. Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
  492. Assert.Equal(4, n);
  493. }
  494. [Fact]
  495. public void MemoizeLambda_Arguments()
  496. {
  497. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, xs => xs));
  498. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, null));
  499. }
  500. [Fact]
  501. public void MemoizeLambda()
  502. {
  503. var n = 0;
  504. var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
  505. Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
  506. Assert.Equal(4, n);
  507. }
  508. [Fact]
  509. public void MemoizeLimitedLambda_Arguments()
  510. {
  511. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, 2, xs => xs));
  512. AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 2, null));
  513. AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 0, xs => xs));
  514. AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, -1, xs => xs));
  515. }
  516. [Fact]
  517. public void MemoizeLimitedLambda()
  518. {
  519. var n = 0;
  520. var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(2, xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
  521. Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
  522. Assert.Equal(4, n);
  523. }
  524. }
  525. }