GenerateTest.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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 System.Threading.Tasks;
  9. using System.Reactive;
  10. using System.Reactive.Concurrency;
  11. using System.Reactive.Linq;
  12. using Microsoft.Reactive.Testing;
  13. using Xunit;
  14. using ReactiveTests.Dummies;
  15. using System.Reflection;
  16. using System.Threading;
  17. using System.Reactive.Disposables;
  18. using System.Reactive.Subjects;
  19. using System.Runtime.CompilerServices;
  20. namespace ReactiveTests.Tests
  21. {
  22. public class GenerateTest : ReactiveTest
  23. {
  24. #region + Non-timed +
  25. [Fact]
  26. public void Generate_ArgumentChecking()
  27. {
  28. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, (IScheduler)null));
  29. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyScheduler.Instance));
  30. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null, DummyScheduler.Instance));
  31. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance, DummyScheduler.Instance));
  32. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyScheduler.Instance).Subscribe(null));
  33. }
  34. [Fact]
  35. public void Generate_Finite()
  36. {
  37. var scheduler = new TestScheduler();
  38. var res = scheduler.Start(() =>
  39. Observable.Generate(0, x => x <= 3, x => x + 1, x => x, scheduler)
  40. );
  41. res.Messages.AssertEqual(
  42. OnNext(201, 0),
  43. OnNext(202, 1),
  44. OnNext(203, 2),
  45. OnNext(204, 3),
  46. OnCompleted<int>(205)
  47. );
  48. }
  49. [Fact]
  50. public void Generate_Throw_Condition()
  51. {
  52. var scheduler = new TestScheduler();
  53. var ex = new Exception();
  54. var res = scheduler.Start(() =>
  55. Observable.Generate(0, new Func<int, bool>(x => { throw ex; }), x => x + 1, x => x, scheduler)
  56. );
  57. res.Messages.AssertEqual(
  58. OnError<int>(201, ex)
  59. );
  60. }
  61. [Fact]
  62. public void Generate_Throw_ResultSelector()
  63. {
  64. var scheduler = new TestScheduler();
  65. var ex = new Exception();
  66. var res = scheduler.Start(() =>
  67. Observable.Generate(0, x => true, x => x + 1, new Func<int, int>(x => { throw ex; }), scheduler)
  68. );
  69. res.Messages.AssertEqual(
  70. OnError<int>(201, ex)
  71. );
  72. }
  73. [Fact]
  74. public void Generate_Throw_Iterate()
  75. {
  76. var scheduler = new TestScheduler();
  77. var ex = new Exception();
  78. var res = scheduler.Start(() =>
  79. Observable.Generate(0, x => true, new Func<int, int>(x => { throw ex; }), x => x, scheduler)
  80. );
  81. res.Messages.AssertEqual(
  82. OnNext(201, 0),
  83. OnError<int>(202, ex)
  84. );
  85. }
  86. [Fact]
  87. public void Generate_Dispose()
  88. {
  89. var scheduler = new TestScheduler();
  90. var res = scheduler.Start(() =>
  91. Observable.Generate(0, x => true, x => x + 1, x => x, scheduler),
  92. 203
  93. );
  94. res.Messages.AssertEqual(
  95. OnNext(201, 0),
  96. OnNext(202, 1)
  97. );
  98. }
  99. [Fact]
  100. public void Generate_DefaultScheduler_ArgumentChecking()
  101. {
  102. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance));
  103. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null));
  104. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance));
  105. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance).Subscribe(null));
  106. }
  107. [Fact]
  108. public void Generate_DefaultScheduler()
  109. {
  110. Observable.Generate(0, x => x < 10, x => x + 1, x => x).AssertEqual(Observable.Generate(0, x => x < 10, x => x + 1, x => x, DefaultScheduler.Instance));
  111. }
  112. #if !NO_PERF
  113. [Fact]
  114. public void Generate_LongRunning1()
  115. {
  116. var start = default(ManualResetEvent);
  117. var end = default(ManualResetEvent);
  118. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  119. var xs = Observable.Generate(0, x => x < 100, x => x + 1, x => x, s);
  120. var lst = new List<int>();
  121. var done = false;
  122. xs.Subscribe(x => { lst.Add(x); }, () => done = true);
  123. end.WaitOne();
  124. Assert.True(lst.SequenceEqual(Enumerable.Range(0, 100)));
  125. Assert.True(done);
  126. }
  127. [Fact]
  128. [MethodImpl(MethodImplOptions.NoOptimization)]
  129. public void Generate_LongRunning2()
  130. {
  131. var start = default(ManualResetEvent);
  132. var end = default(ManualResetEvent);
  133. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  134. var xs = Observable.Generate(0, _ => true, x => x + 1, x => x, s);
  135. var lst = new List<int>();
  136. var d = xs.Subscribe(x => { lst.Add(x); });
  137. start.WaitOne();
  138. while (lst.Count < 100)
  139. ;
  140. d.Dispose();
  141. end.WaitOne();
  142. Assert.True(lst.Take(100).SequenceEqual(Enumerable.Range(0, 100)));
  143. }
  144. [Fact]
  145. public void Generate_LongRunning_Throw()
  146. {
  147. var start = default(ManualResetEvent);
  148. var end = default(ManualResetEvent);
  149. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  150. var ex = new Exception();
  151. var xs = Observable.Generate(0, x => { if (x < 100) return true; throw ex; }, x => x + 1, x => x, s);
  152. var lst = new List<int>();
  153. var e = default(Exception);
  154. var done = false;
  155. xs.Subscribe(x => { lst.Add(x); }, e_ => e = e_, () => done = true);
  156. end.WaitOne();
  157. Assert.True(lst.SequenceEqual(Enumerable.Range(0, 100)));
  158. Assert.Same(ex, e);
  159. Assert.False(done);
  160. }
  161. #endif
  162. #endregion
  163. #region + Timed +
  164. [Fact]
  165. public void Generate_TimeSpan_ArgumentChecking()
  166. {
  167. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance, (IScheduler)null));
  168. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance, DummyScheduler.Instance));
  169. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null, DummyFunc<int, TimeSpan>.Instance, DummyScheduler.Instance));
  170. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance, DummyScheduler.Instance));
  171. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, (Func<int, TimeSpan>)null, DummyScheduler.Instance));
  172. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance, DummyScheduler.Instance).Subscribe(null));
  173. }
  174. [Fact]
  175. public void Generate_TimeSpan_Finite()
  176. {
  177. var scheduler = new TestScheduler();
  178. var res = scheduler.Start(() =>
  179. Observable.Generate(0, x => x <= 3, x => x + 1, x => x, x => TimeSpan.FromTicks(x + 1), scheduler)
  180. );
  181. res.Messages.AssertEqual(
  182. OnNext(202, 0),
  183. OnNext(204, 1),
  184. OnNext(207, 2),
  185. OnNext(211, 3),
  186. OnCompleted<int>(211)
  187. );
  188. }
  189. [Fact]
  190. public void Generate_TimeSpan_Throw_Condition()
  191. {
  192. var scheduler = new TestScheduler();
  193. var ex = new Exception();
  194. var res = scheduler.Start(() =>
  195. Observable.Generate(0, new Func<int, bool>(x => { throw ex; }), x => x + 1, x => x, x => TimeSpan.FromTicks(x + 1), scheduler)
  196. );
  197. res.Messages.AssertEqual(
  198. OnError<int>(201, ex)
  199. );
  200. }
  201. [Fact]
  202. public void Generate_TimeSpan_Throw_ResultSelector()
  203. {
  204. var scheduler = new TestScheduler();
  205. var ex = new Exception();
  206. var res = scheduler.Start(() =>
  207. Observable.Generate(0, x => true, x => x + 1, new Func<int, int>(x => { throw ex; }), x => TimeSpan.FromTicks(x + 1), scheduler)
  208. );
  209. res.Messages.AssertEqual(
  210. OnError<int>(201, ex)
  211. );
  212. }
  213. [Fact]
  214. public void Generate_TimeSpan_Throw_Iterate()
  215. {
  216. var scheduler = new TestScheduler();
  217. var ex = new Exception();
  218. var res = scheduler.Start(() =>
  219. Observable.Generate(0, x => true, new Func<int, int>(x => { throw ex; }), x => x, x => TimeSpan.FromTicks(x + 1), scheduler)
  220. );
  221. res.Messages.AssertEqual(
  222. OnNext(202, 0),
  223. OnError<int>(202, ex)
  224. );
  225. }
  226. [Fact]
  227. public void Generate_TimeSpan_Throw_TimeSelector()
  228. {
  229. var scheduler = new TestScheduler();
  230. var ex = new Exception();
  231. var res = scheduler.Start(() =>
  232. Observable.Generate(0, x => true, x => x + 1, x => x, new Func<int, TimeSpan>(x => { throw ex; }), scheduler)
  233. );
  234. res.Messages.AssertEqual(
  235. OnError<int>(201, ex)
  236. );
  237. }
  238. [Fact]
  239. public void Generate_TimeSpan_Dispose()
  240. {
  241. var scheduler = new TestScheduler();
  242. var res = scheduler.Start(() =>
  243. Observable.Generate(0, x => true, x => x + 1, x => x, x => TimeSpan.FromTicks(x + 1), scheduler),
  244. 210
  245. );
  246. res.Messages.AssertEqual(
  247. OnNext(202, 0),
  248. OnNext(204, 1),
  249. OnNext(207, 2)
  250. );
  251. }
  252. [Fact]
  253. public void Generate_TimeSpan_DefaultScheduler_ArgumentChecking()
  254. {
  255. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance));
  256. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null, DummyFunc<int, TimeSpan>.Instance));
  257. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance));
  258. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, (Func<int, TimeSpan>)null));
  259. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, TimeSpan>.Instance).Subscribe(null));
  260. }
  261. [Fact]
  262. public void Generate_TimeSpan_DefaultScheduler()
  263. {
  264. Observable.Generate(0, x => x < 10, x => x + 1, x => x, x => TimeSpan.FromMilliseconds(x)).AssertEqual(Observable.Generate(0, x => x < 10, x => x + 1, x => x, x => TimeSpan.FromMilliseconds(x), DefaultScheduler.Instance));
  265. }
  266. [Fact]
  267. public void Generate_DateTimeOffset_ArgumentChecking()
  268. {
  269. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance, (IScheduler)null));
  270. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance, DummyScheduler.Instance));
  271. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null, DummyFunc<int, DateTimeOffset>.Instance, DummyScheduler.Instance));
  272. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance, DummyScheduler.Instance));
  273. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, (Func<int, DateTimeOffset>)null, DummyScheduler.Instance));
  274. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance, DummyScheduler.Instance).Subscribe(null));
  275. }
  276. [Fact]
  277. public void Generate_DateTimeOffset_Finite()
  278. {
  279. var scheduler = new TestScheduler();
  280. var res = scheduler.Start(() =>
  281. Observable.Generate(0, x => x <= 3, x => x + 1, x => x, x => scheduler.Now.AddTicks(x + 1), scheduler)
  282. );
  283. res.Messages.AssertEqual(
  284. OnNext(202, 0),
  285. OnNext(204, 1),
  286. OnNext(207, 2),
  287. OnNext(211, 3),
  288. OnCompleted<int>(211)
  289. );
  290. }
  291. [Fact]
  292. public void Generate_DateTimeOffset_Throw_Condition()
  293. {
  294. var scheduler = new TestScheduler();
  295. var ex = new Exception();
  296. var res = scheduler.Start(() =>
  297. Observable.Generate(0, new Func<int, bool>(x => { throw ex; }), x => x + 1, x => x, x => scheduler.Now.AddTicks(x + 1), scheduler)
  298. );
  299. res.Messages.AssertEqual(
  300. OnError<int>(201, ex)
  301. );
  302. }
  303. [Fact]
  304. public void Generate_DateTimeOffset_Throw_ResultSelector()
  305. {
  306. var scheduler = new TestScheduler();
  307. var ex = new Exception();
  308. var res = scheduler.Start(() =>
  309. Observable.Generate(0, x => true, x => x + 1, new Func<int, int>(x => { throw ex; }), x => scheduler.Now.AddTicks(x + 1), scheduler)
  310. );
  311. res.Messages.AssertEqual(
  312. OnError<int>(201, ex)
  313. );
  314. }
  315. [Fact]
  316. public void Generate_DateTimeOffset_Throw_Iterate()
  317. {
  318. var scheduler = new TestScheduler();
  319. var ex = new Exception();
  320. var res = scheduler.Start(() =>
  321. Observable.Generate(0, x => true, new Func<int, int>(x => { throw ex; }), x => x, x => scheduler.Now.AddTicks(x + 1), scheduler)
  322. );
  323. res.Messages.AssertEqual(
  324. OnNext(202, 0),
  325. OnError<int>(202, ex)
  326. );
  327. }
  328. [Fact]
  329. public void Generate_DateTimeOffset_Throw_TimeSelector()
  330. {
  331. var scheduler = new TestScheduler();
  332. var ex = new Exception();
  333. var res = scheduler.Start(() =>
  334. Observable.Generate(0, x => true, x => x + 1, x => x, new Func<int, DateTimeOffset>(x => { throw ex; }), scheduler)
  335. );
  336. res.Messages.AssertEqual(
  337. OnError<int>(201, ex)
  338. );
  339. }
  340. [Fact]
  341. public void Generate_DateTimeOffset_Dispose()
  342. {
  343. var scheduler = new TestScheduler();
  344. var res = scheduler.Start(() =>
  345. Observable.Generate(0, x => true, x => x + 1, x => x, x => scheduler.Now.AddTicks(x + 1), scheduler),
  346. 210
  347. );
  348. res.Messages.AssertEqual(
  349. OnNext(202, 0),
  350. OnNext(204, 1),
  351. OnNext(207, 2)
  352. );
  353. }
  354. [Fact]
  355. public void Generate_DateTimeOffset_DefaultScheduler_ArgumentChecking()
  356. {
  357. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, (Func<int, bool>)null, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance));
  358. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, (Func<int, int>)null, DummyFunc<int, DateTimeOffset>.Instance));
  359. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, (Func<int, int>)null, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance));
  360. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, (Func<int, DateTimeOffset>)null));
  361. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Generate(0, DummyFunc<int, bool>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, int>.Instance, DummyFunc<int, DateTimeOffset>.Instance).Subscribe(null));
  362. }
  363. [Fact]
  364. public void Generate_DateTimeOffset_DefaultScheduler()
  365. {
  366. Observable.Generate(0, x => x < 10, x => x + 1, x => x, x => DateTimeOffset.Now.AddMilliseconds(x)).AssertEqual(Observable.Generate(0, x => x < 10, x => x + 1, x => x, x => DateTimeOffset.Now.AddMilliseconds(x), DefaultScheduler.Instance));
  367. }
  368. #endregion
  369. }
  370. }