RepeatTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  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 RepeatTest : ReactiveTest
  23. {
  24. [Fact]
  25. public void Repeat_Value_Count_ArgumentChecking()
  26. {
  27. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(1, 0, default(IScheduler)));
  28. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => Observable.Repeat(1, -1, DummyScheduler.Instance));
  29. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(1, 1, DummyScheduler.Instance).Subscribe(null));
  30. }
  31. [Fact]
  32. public void Repeat_Value_Count_Zero()
  33. {
  34. var scheduler = new TestScheduler();
  35. var res = scheduler.Start(() =>
  36. Observable.Repeat(42, 0, scheduler)
  37. );
  38. #if !NO_PERF
  39. res.Messages.AssertEqual(
  40. OnCompleted<int>(201)
  41. );
  42. #else
  43. res.Messages.AssertEqual(
  44. OnCompleted<int>(200)
  45. );
  46. #endif
  47. }
  48. [Fact]
  49. public void Repeat_Value_Count_One()
  50. {
  51. var scheduler = new TestScheduler();
  52. var res = scheduler.Start(() =>
  53. Observable.Repeat(42, 1, scheduler)
  54. );
  55. res.Messages.AssertEqual(
  56. OnNext(201, 42),
  57. OnCompleted<int>(201)
  58. );
  59. }
  60. [Fact]
  61. public void Repeat_Value_Count_Ten()
  62. {
  63. var scheduler = new TestScheduler();
  64. var res = scheduler.Start(() =>
  65. Observable.Repeat(42, 10, scheduler)
  66. );
  67. res.Messages.AssertEqual(
  68. OnNext(201, 42),
  69. OnNext(202, 42),
  70. OnNext(203, 42),
  71. OnNext(204, 42),
  72. OnNext(205, 42),
  73. OnNext(206, 42),
  74. OnNext(207, 42),
  75. OnNext(208, 42),
  76. OnNext(209, 42),
  77. OnNext(210, 42),
  78. OnCompleted<int>(210)
  79. );
  80. }
  81. [Fact]
  82. public void Repeat_Value_Count_Dispose()
  83. {
  84. var scheduler = new TestScheduler();
  85. var res = scheduler.Start(() =>
  86. Observable.Repeat(42, 10, scheduler),
  87. 207
  88. );
  89. res.Messages.AssertEqual(
  90. OnNext(201, 42),
  91. OnNext(202, 42),
  92. OnNext(203, 42),
  93. OnNext(204, 42),
  94. OnNext(205, 42),
  95. OnNext(206, 42)
  96. );
  97. }
  98. [Fact]
  99. public void Repeat_Value_Count_Default_ArgumentChecking()
  100. {
  101. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => Observable.Repeat(1, -1));
  102. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(1, 1).Subscribe(null));
  103. }
  104. [Fact]
  105. public void Repeat_Value_Count_Default()
  106. {
  107. Observable.Repeat(42, 10).AssertEqual(Observable.Repeat(42, 10, DefaultScheduler.Instance));
  108. }
  109. [Fact]
  110. public void Repeat_Value_ArgumentChecking()
  111. {
  112. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(1, (IScheduler)null));
  113. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(DummyScheduler.Instance, 1).Subscribe(null));
  114. }
  115. [Fact]
  116. public void Repeat_Value()
  117. {
  118. var scheduler = new TestScheduler();
  119. var res = scheduler.Start(() =>
  120. Observable.Repeat(42, scheduler),
  121. 207
  122. );
  123. res.Messages.AssertEqual(
  124. OnNext(201, 42),
  125. OnNext(202, 42),
  126. OnNext(203, 42),
  127. OnNext(204, 42),
  128. OnNext(205, 42),
  129. OnNext(206, 42)
  130. );
  131. }
  132. [Fact]
  133. public void Repeat_Value_Default_ArgumentChecking()
  134. {
  135. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat(1).Subscribe(null));
  136. }
  137. [Fact]
  138. public void Repeat_Value_Default()
  139. {
  140. Observable.Repeat(42).Take(100).AssertEqual(Observable.Repeat(42, DefaultScheduler.Instance).Take(100));
  141. }
  142. #if !NO_PERF
  143. [Fact]
  144. public void Repeat_Count_LongRunning1()
  145. {
  146. var start = default(ManualResetEvent);
  147. var end = default(ManualResetEvent);
  148. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  149. var xs = Observable.Repeat(42, 100, s);
  150. var lst = new List<int>();
  151. var done = false;
  152. xs.Subscribe(x => { lst.Add(x); }, () => done = true);
  153. end.WaitOne();
  154. Assert.True(lst.SequenceEqual(Enumerable.Repeat(42, 100)));
  155. Assert.True(done);
  156. }
  157. [Fact]
  158. [MethodImpl(MethodImplOptions.NoOptimization)]
  159. public void Repeat_Count_LongRunning2()
  160. {
  161. var start = default(ManualResetEvent);
  162. var end = default(ManualResetEvent);
  163. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  164. var xs = Observable.Repeat(42, int.MaxValue, s);
  165. var lst = new List<int>();
  166. var d = xs.Subscribe(x => { lst.Add(x); });
  167. start.WaitOne();
  168. while (lst.Count < 100)
  169. ;
  170. d.Dispose();
  171. end.WaitOne();
  172. Assert.True(true);
  173. }
  174. [Fact]
  175. [MethodImpl(MethodImplOptions.NoOptimization)]
  176. public void Repeat_Inf_LongRunning()
  177. {
  178. var start = default(ManualResetEvent);
  179. var end = default(ManualResetEvent);
  180. var s = new TestLongRunningScheduler(x => start = x, x => end = x);
  181. var xs = Observable.Repeat(42, s);
  182. var lst = new List<int>();
  183. var d = xs.Subscribe(x => { lst.Add(x); });
  184. start.WaitOne();
  185. while (lst.Count < 100)
  186. ;
  187. d.Dispose();
  188. end.WaitOne();
  189. Assert.True(true);
  190. }
  191. #endif
  192. [Fact]
  193. public void Repeat_Observable_ArgumentChecking()
  194. {
  195. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat<int>(null));
  196. ReactiveAssert.Throws<ArgumentNullException>(() => DummyObservable<int>.Instance.Repeat().Subscribe(null));
  197. }
  198. [Fact]
  199. public void Repeat_Observable_Basic()
  200. {
  201. var scheduler = new TestScheduler();
  202. var xs = scheduler.CreateColdObservable(
  203. OnNext(100, 1),
  204. OnNext(150, 2),
  205. OnNext(200, 3),
  206. OnCompleted<int>(250)
  207. );
  208. var res = scheduler.Start(() =>
  209. xs.Repeat()
  210. );
  211. res.Messages.AssertEqual(
  212. OnNext(300, 1),
  213. OnNext(350, 2),
  214. OnNext(400, 3),
  215. OnNext(550, 1),
  216. OnNext(600, 2),
  217. OnNext(650, 3),
  218. OnNext(800, 1),
  219. OnNext(850, 2),
  220. OnNext(900, 3)
  221. );
  222. xs.Subscriptions.AssertEqual(
  223. Subscribe(200, 450),
  224. Subscribe(450, 700),
  225. Subscribe(700, 950),
  226. Subscribe(950, 1000)
  227. );
  228. }
  229. [Fact]
  230. public void Repeat_Observable_Infinite()
  231. {
  232. var scheduler = new TestScheduler();
  233. var xs = scheduler.CreateColdObservable(
  234. OnNext(100, 1),
  235. OnNext(150, 2),
  236. OnNext(200, 3)
  237. );
  238. var res = scheduler.Start(() =>
  239. xs.Repeat()
  240. );
  241. res.Messages.AssertEqual(
  242. OnNext(300, 1),
  243. OnNext(350, 2),
  244. OnNext(400, 3)
  245. );
  246. xs.Subscriptions.AssertEqual(
  247. Subscribe(200, 1000)
  248. );
  249. }
  250. [Fact]
  251. public void Repeat_Observable_Error()
  252. {
  253. var scheduler = new TestScheduler();
  254. var ex = new Exception();
  255. var xs = scheduler.CreateColdObservable(
  256. OnNext(100, 1),
  257. OnNext(150, 2),
  258. OnNext(200, 3),
  259. OnError<int>(250, ex)
  260. );
  261. var res = scheduler.Start(() =>
  262. xs.Repeat()
  263. );
  264. res.Messages.AssertEqual(
  265. OnNext(300, 1),
  266. OnNext(350, 2),
  267. OnNext(400, 3),
  268. OnError<int>(450, ex)
  269. );
  270. xs.Subscriptions.AssertEqual(
  271. Subscribe(200, 450)
  272. );
  273. }
  274. [Fact]
  275. public void Repeat_Observable_Throws()
  276. {
  277. var scheduler1 = new TestScheduler();
  278. var xs = Observable.Return(1, scheduler1).Repeat();
  279. xs.Subscribe(x => { throw new InvalidOperationException(); });
  280. ReactiveAssert.Throws<InvalidOperationException>(() => scheduler1.Start());
  281. var scheduler2 = new TestScheduler();
  282. var ys = Observable.Throw<int>(new Exception(), scheduler2).Repeat();
  283. ys.Subscribe(x => { }, ex => { throw new InvalidOperationException(); });
  284. ReactiveAssert.Throws<InvalidOperationException>(() => scheduler2.Start());
  285. var scheduler3 = new TestScheduler();
  286. var zs = Observable.Return(1, scheduler3).Repeat();
  287. var d = zs.Subscribe(x => { }, ex => { }, () => { throw new InvalidOperationException(); });
  288. scheduler3.ScheduleAbsolute(210, () => d.Dispose());
  289. scheduler3.Start();
  290. var xss = Observable.Create<int>(new Func<IObserver<int>, Action>(o => { throw new InvalidOperationException(); })).Repeat();
  291. ReactiveAssert.Throws<InvalidOperationException>(() => xss.Subscribe());
  292. }
  293. [Fact]
  294. public void Repeat_Observable_Default_ArgumentChecking()
  295. {
  296. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat<int>((IObservable<int>)null));
  297. ReactiveAssert.Throws<ArgumentNullException>(() => DummyObservable<int>.Instance.Repeat().Subscribe(null));
  298. }
  299. [Fact]
  300. public void Repeat_Observable_RepeatCount_ArgumentChecking()
  301. {
  302. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat<int>(null, 0));
  303. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => DummyObservable<int>.Instance.Repeat(-1));
  304. ReactiveAssert.Throws<ArgumentNullException>(() => DummyObservable<int>.Instance.Repeat(0).Subscribe(null));
  305. }
  306. [Fact]
  307. public void Repeat_Observable_RepeatCount_Basic()
  308. {
  309. var scheduler = new TestScheduler();
  310. var xs = scheduler.CreateColdObservable(
  311. OnNext(5, 1),
  312. OnNext(10, 2),
  313. OnNext(15, 3),
  314. OnCompleted<int>(20)
  315. );
  316. var res = scheduler.Start(() =>
  317. xs.Repeat(3)
  318. );
  319. res.Messages.AssertEqual(
  320. OnNext(205, 1),
  321. OnNext(210, 2),
  322. OnNext(215, 3),
  323. OnNext(225, 1),
  324. OnNext(230, 2),
  325. OnNext(235, 3),
  326. OnNext(245, 1),
  327. OnNext(250, 2),
  328. OnNext(255, 3),
  329. OnCompleted<int>(260)
  330. );
  331. xs.Subscriptions.AssertEqual(
  332. Subscribe(200, 220),
  333. Subscribe(220, 240),
  334. Subscribe(240, 260)
  335. );
  336. }
  337. [Fact]
  338. public void Repeat_Observable_RepeatCount_Dispose()
  339. {
  340. var scheduler = new TestScheduler();
  341. var xs = scheduler.CreateColdObservable(
  342. OnNext(5, 1),
  343. OnNext(10, 2),
  344. OnNext(15, 3),
  345. OnCompleted<int>(20)
  346. );
  347. var res = scheduler.Start(() =>
  348. xs.Repeat(3), 231
  349. );
  350. res.Messages.AssertEqual(
  351. OnNext(205, 1),
  352. OnNext(210, 2),
  353. OnNext(215, 3),
  354. OnNext(225, 1),
  355. OnNext(230, 2)
  356. );
  357. xs.Subscriptions.AssertEqual(
  358. Subscribe(200, 220),
  359. Subscribe(220, 231)
  360. );
  361. }
  362. [Fact]
  363. public void Repeat_Observable_RepeatCount_Infinite()
  364. {
  365. var scheduler = new TestScheduler();
  366. var xs = scheduler.CreateColdObservable(
  367. OnNext(100, 1),
  368. OnNext(150, 2),
  369. OnNext(200, 3)
  370. );
  371. var res = scheduler.Start(() =>
  372. xs.Repeat(3)
  373. );
  374. res.Messages.AssertEqual(
  375. OnNext(300, 1),
  376. OnNext(350, 2),
  377. OnNext(400, 3)
  378. );
  379. xs.Subscriptions.AssertEqual(
  380. Subscribe(200, 1000)
  381. );
  382. }
  383. [Fact]
  384. public void Repeat_Observable_RepeatCount_Error()
  385. {
  386. var scheduler = new TestScheduler();
  387. var ex = new Exception();
  388. var xs = scheduler.CreateColdObservable(
  389. OnNext(100, 1),
  390. OnNext(150, 2),
  391. OnNext(200, 3),
  392. OnError<int>(250, ex)
  393. );
  394. var res = scheduler.Start(() =>
  395. xs.Repeat(3)
  396. );
  397. res.Messages.AssertEqual(
  398. OnNext(300, 1),
  399. OnNext(350, 2),
  400. OnNext(400, 3),
  401. OnError<int>(450, ex)
  402. );
  403. xs.Subscriptions.AssertEqual(
  404. Subscribe(200, 450)
  405. );
  406. }
  407. [Fact]
  408. public void Repeat_Observable_RepeatCount_Throws()
  409. {
  410. var scheduler1 = new TestScheduler();
  411. var xs = Observable.Return(1, scheduler1).Repeat(3);
  412. xs.Subscribe(x => { throw new InvalidOperationException(); });
  413. ReactiveAssert.Throws<InvalidOperationException>(() => scheduler1.Start());
  414. var scheduler2 = new TestScheduler();
  415. var ys = Observable.Throw<int>(new Exception(), scheduler2).Repeat(3);
  416. ys.Subscribe(x => { }, ex => { throw new InvalidOperationException(); });
  417. ReactiveAssert.Throws<InvalidOperationException>(() => scheduler2.Start());
  418. var scheduler3 = new TestScheduler();
  419. var zs = Observable.Return(1, scheduler3).Repeat(100);
  420. var d = zs.Subscribe(x => { }, ex => { }, () => { throw new InvalidOperationException(); });
  421. scheduler3.ScheduleAbsolute(10, () => d.Dispose());
  422. scheduler3.Start();
  423. var xss = Observable.Create<int>(new Func<IObserver<int>, Action>(o => { throw new InvalidOperationException(); })).Repeat(3);
  424. ReactiveAssert.Throws<InvalidOperationException>(() => xss.Subscribe());
  425. }
  426. [Fact]
  427. public void Repeat_Observable_RepeatCount_Default_ArgumentChecking()
  428. {
  429. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Repeat<int>(default(IObservable<int>), 0));
  430. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => DummyObservable<int>.Instance.Repeat(-1));
  431. ReactiveAssert.Throws<ArgumentNullException>(() => DummyObservable<int>.Instance.Repeat(0).Subscribe(null));
  432. }
  433. }
  434. }