1
0

Publish.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using Xunit;
  9. namespace Tests
  10. {
  11. public class Publish : Tests
  12. {
  13. [Fact]
  14. public void Publish_Arguments()
  15. {
  16. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int>(null));
  17. }
  18. [Fact]
  19. public void Publish0()
  20. {
  21. var n = 0;
  22. var rng = Tick(i => n += i).Publish();
  23. var e1 = rng.GetEnumerator();
  24. var e2 = rng.GetEnumerator();
  25. HasNext(e1, 0);
  26. Assert.Equal(0, n);
  27. HasNext(e1, 1);
  28. Assert.Equal(1, n);
  29. HasNext(e1, 2);
  30. Assert.Equal(3, n);
  31. HasNext(e2, 0);
  32. Assert.Equal(3, n);
  33. HasNext(e1, 3);
  34. Assert.Equal(6, n);
  35. HasNext(e2, 1);
  36. Assert.Equal(6, n);
  37. HasNext(e2, 2);
  38. Assert.Equal(6, n);
  39. HasNext(e2, 3);
  40. Assert.Equal(6, n);
  41. HasNext(e2, 4);
  42. Assert.Equal(10, n);
  43. HasNext(e1, 4);
  44. Assert.Equal(10, n);
  45. }
  46. [Fact]
  47. public void Publish1()
  48. {
  49. var rng = Enumerable.Range(0, 5).Publish();
  50. var e1 = rng.GetEnumerator();
  51. HasNext(e1, 0);
  52. HasNext(e1, 1);
  53. HasNext(e1, 2);
  54. HasNext(e1, 3);
  55. HasNext(e1, 4);
  56. NoNext(e1);
  57. }
  58. [Fact]
  59. public void Publish2()
  60. {
  61. var rng = Enumerable.Range(0, 5).Publish();
  62. var e1 = rng.GetEnumerator();
  63. var e2 = rng.GetEnumerator();
  64. HasNext(e1, 0);
  65. HasNext(e2, 0);
  66. HasNext(e1, 1);
  67. HasNext(e2, 1);
  68. HasNext(e1, 2);
  69. HasNext(e2, 2);
  70. HasNext(e1, 3);
  71. HasNext(e2, 3);
  72. HasNext(e1, 4);
  73. HasNext(e2, 4);
  74. NoNext(e1);
  75. NoNext(e2);
  76. }
  77. [Fact]
  78. public void Publish3()
  79. {
  80. var rng = Enumerable.Range(0, 5).Publish();
  81. var e1 = rng.GetEnumerator();
  82. var e2 = rng.GetEnumerator();
  83. HasNext(e1, 0);
  84. HasNext(e1, 1);
  85. HasNext(e1, 2);
  86. HasNext(e1, 3);
  87. HasNext(e1, 4);
  88. HasNext(e2, 0);
  89. HasNext(e2, 1);
  90. HasNext(e2, 2);
  91. HasNext(e2, 3);
  92. HasNext(e2, 4);
  93. NoNext(e1);
  94. NoNext(e2);
  95. }
  96. [Fact]
  97. public void Publish4()
  98. {
  99. var rng = Enumerable.Range(0, 5).Publish();
  100. var e1 = rng.GetEnumerator();
  101. HasNext(e1, 0);
  102. HasNext(e1, 1);
  103. HasNext(e1, 2);
  104. var e2 = rng.GetEnumerator();
  105. HasNext(e1, 3);
  106. HasNext(e1, 4);
  107. HasNext(e2, 3);
  108. HasNext(e2, 4);
  109. NoNext(e1);
  110. NoNext(e2);
  111. }
  112. [Fact]
  113. public void Publish5()
  114. {
  115. var rng = Enumerable.Range(0, 5).Publish();
  116. var e1 = rng.GetEnumerator();
  117. HasNext(e1, 0);
  118. HasNext(e1, 1);
  119. HasNext(e1, 2);
  120. e1.Dispose();
  121. var e2 = rng.GetEnumerator();
  122. HasNext(e2, 3);
  123. HasNext(e2, 4);
  124. NoNext(e2);
  125. }
  126. [Fact]
  127. public void Publish6()
  128. {
  129. var ex = new MyException();
  130. var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Publish();
  131. var e1 = rng.GetEnumerator();
  132. var e2 = rng.GetEnumerator();
  133. HasNext(e1, 0);
  134. HasNext(e1, 1);
  135. AssertThrows<MyException>(() => e1.MoveNext());
  136. HasNext(e2, 0);
  137. HasNext(e2, 1);
  138. AssertThrows<MyException>(() => e2.MoveNext());
  139. }
  140. class MyException : Exception
  141. {
  142. }
  143. [Fact]
  144. public void Publish7()
  145. {
  146. var rng = Enumerable.Range(0, 5).Publish();
  147. var e1 = rng.GetEnumerator();
  148. HasNext(e1, 0);
  149. HasNext(e1, 1);
  150. HasNext(e1, 2);
  151. var e2 = rng.GetEnumerator();
  152. HasNext(e2, 3);
  153. HasNext(e2, 4);
  154. NoNext(e2);
  155. HasNext(e1, 3);
  156. HasNext(e1, 4);
  157. NoNext(e2);
  158. var e3 = rng.GetEnumerator();
  159. NoNext(e3);
  160. }
  161. [Fact]
  162. public void Publish8()
  163. {
  164. var rng = Enumerable.Range(0, 5).Publish();
  165. var e1 = rng.GetEnumerator();
  166. HasNext(e1, 0);
  167. HasNext(e1, 1);
  168. HasNext(e1, 2);
  169. rng.Dispose();
  170. AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
  171. AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
  172. AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
  173. }
  174. [Fact]
  175. public void Publish9()
  176. {
  177. var rng = Enumerable.Range(0, 5).Publish();
  178. var e1 = ((IEnumerable)rng).GetEnumerator();
  179. Assert.True(e1.MoveNext());
  180. Assert.Equal(0, (int)e1.Current);
  181. }
  182. [Fact]
  183. public void Publish10()
  184. {
  185. var rnd = Rand().Take(1000).Publish();
  186. Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
  187. }
  188. [Fact]
  189. public void PublishLambda_Arguments()
  190. {
  191. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(null, xs => xs));
  192. AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(new[] { 1 }, null));
  193. }
  194. [Fact]
  195. public void PublishLambda()
  196. {
  197. var n = 0;
  198. var res = Enumerable.Range(0, 10).Do(_ => n++).Publish(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
  199. Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
  200. Assert.Equal(4, n);
  201. }
  202. private static IEnumerable<int> Tick(Action<int> t)
  203. {
  204. var i = 0;
  205. while (true)
  206. {
  207. t(i);
  208. yield return i++;
  209. }
  210. }
  211. private static readonly Random s_rand = new Random();
  212. private static IEnumerable<int> Rand()
  213. {
  214. while (true)
  215. yield return s_rand.Next();
  216. }
  217. }
  218. }