RepeatTest.cs 16 KB

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