SampleTest.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System;
  5. using System.Linq;
  6. using System.Reactive.Concurrency;
  7. using System.Reactive.Linq;
  8. using Microsoft.Reactive.Testing;
  9. using Microsoft.VisualStudio.TestTools.UnitTesting;
  10. using Assert = Xunit.Assert;
  11. namespace ReactiveTests.Tests
  12. {
  13. [TestClass]
  14. public class SampleTest : ReactiveTest
  15. {
  16. [TestMethod]
  17. public void Sample_ArgumentChecking()
  18. {
  19. var scheduler = new TestScheduler();
  20. var someObservable = Observable.Empty<int>();
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Sample(default(IObservable<int>), TimeSpan.Zero));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Sample(default(IObservable<int>), TimeSpan.Zero, scheduler));
  23. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Sample(someObservable, TimeSpan.Zero, null));
  24. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => Observable.Sample(someObservable, TimeSpan.FromSeconds(-1)));
  25. ReactiveAssert.Throws<ArgumentOutOfRangeException>(() => Observable.Sample(someObservable, TimeSpan.FromSeconds(-1), scheduler));
  26. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Sample(default(IObservable<int>), someObservable));
  27. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Sample(someObservable, default(IObservable<int>)));
  28. }
  29. [TestMethod]
  30. public void Sample_Regular()
  31. {
  32. var scheduler = new TestScheduler();
  33. var xs = scheduler.CreateHotObservable(
  34. OnNext(150, 1),
  35. OnNext(210, 2),
  36. OnNext(230, 3),
  37. OnNext(260, 4),
  38. OnNext(300, 5),
  39. OnNext(350, 6),
  40. OnNext(380, 7),
  41. OnCompleted<int>(390)
  42. );
  43. var res = scheduler.Start(() =>
  44. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  45. );
  46. res.Messages.AssertEqual(
  47. OnNext(250, 3),
  48. OnNext(300, 5), /* CHECK: boundary of sampling */
  49. OnNext(350, 6),
  50. OnNext(400, 7), /* Sample in last bucket */
  51. OnCompleted<int>(400)
  52. );
  53. xs.Subscriptions.AssertEqual(
  54. Subscribe(200, 390)
  55. );
  56. }
  57. [TestMethod]
  58. public void Sample_Periodic_Regular()
  59. {
  60. var scheduler = new PeriodicTestScheduler();
  61. var xs = scheduler.CreateHotObservable(
  62. OnNext(150, 1),
  63. OnNext(210, 2),
  64. OnNext(230, 3),
  65. OnNext(260, 4),
  66. OnNext(300, 5),
  67. OnNext(350, 6),
  68. OnNext(380, 7),
  69. OnCompleted<int>(390)
  70. );
  71. var res = scheduler.Start(() =>
  72. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  73. );
  74. res.Messages.AssertEqual(
  75. OnNext(250, 3),
  76. OnNext(300, 5), /* CHECK: boundary of sampling */
  77. OnNext(350, 6),
  78. OnNext(400, 7), /* Sample in last bucket */
  79. OnCompleted<int>(400)
  80. );
  81. xs.Subscriptions.AssertEqual(
  82. Subscribe(200, 390)
  83. );
  84. #if !WINDOWS
  85. scheduler.Timers.AssertEqual(
  86. new TimerRun(200, 400) { 250, 300, 350, 400 }
  87. );
  88. #endif
  89. }
  90. [TestMethod]
  91. public void Sample_ErrorInFlight()
  92. {
  93. var scheduler = new TestScheduler();
  94. var ex = new Exception();
  95. var xs = scheduler.CreateHotObservable(
  96. OnNext(150, 1),
  97. OnNext(210, 2),
  98. OnNext(230, 3),
  99. OnNext(260, 4),
  100. OnNext(300, 5),
  101. OnNext(310, 6),
  102. OnError<int>(330, ex)
  103. );
  104. var res = scheduler.Start(() =>
  105. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  106. );
  107. res.Messages.AssertEqual(
  108. OnNext(250, 3),
  109. OnNext(300, 5), /* CHECK: boundary of sampling */
  110. OnError<int>(330, ex)
  111. );
  112. xs.Subscriptions.AssertEqual(
  113. Subscribe(200, 330)
  114. );
  115. }
  116. [TestMethod]
  117. public void Sample_Periodic_ErrorInFlight()
  118. {
  119. var scheduler = new PeriodicTestScheduler();
  120. var ex = new Exception();
  121. var xs = scheduler.CreateHotObservable(
  122. OnNext(150, 1),
  123. OnNext(210, 2),
  124. OnNext(230, 3),
  125. OnNext(260, 4),
  126. OnNext(300, 5),
  127. OnNext(310, 6),
  128. OnError<int>(330, ex)
  129. );
  130. var res = scheduler.Start(() =>
  131. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  132. );
  133. res.Messages.AssertEqual(
  134. OnNext(250, 3),
  135. OnNext(300, 5), /* CHECK: boundary of sampling */
  136. OnError<int>(330, ex)
  137. );
  138. xs.Subscriptions.AssertEqual(
  139. Subscribe(200, 330)
  140. );
  141. #if !WINDOWS
  142. scheduler.Timers.AssertEqual(
  143. new TimerRun(200, 330) { 250, 300 }
  144. );
  145. #endif
  146. }
  147. [TestMethod]
  148. public void Sample_Empty()
  149. {
  150. var scheduler = new TestScheduler();
  151. var xs = scheduler.CreateHotObservable(
  152. OnNext(150, 1),
  153. OnCompleted<int>(300)
  154. );
  155. var res = scheduler.Start(() =>
  156. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  157. );
  158. res.Messages.AssertEqual(
  159. OnCompleted<int>(300)
  160. );
  161. xs.Subscriptions.AssertEqual(
  162. Subscribe(200, 300)
  163. );
  164. }
  165. [TestMethod]
  166. public void Sample_Periodic_Empty()
  167. {
  168. var scheduler = new PeriodicTestScheduler();
  169. var xs = scheduler.CreateHotObservable(
  170. OnNext(150, 1),
  171. OnCompleted<int>(300)
  172. );
  173. var res = scheduler.Start(() =>
  174. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  175. );
  176. res.Messages.AssertEqual(
  177. OnCompleted<int>(300)
  178. );
  179. xs.Subscriptions.AssertEqual(
  180. Subscribe(200, 300)
  181. );
  182. #if !WINDOWS
  183. scheduler.Timers.AssertEqual(
  184. new TimerRun(200, 300) { 250, 300 }
  185. );
  186. #endif
  187. }
  188. [TestMethod]
  189. public void Sample_Error()
  190. {
  191. var scheduler = new TestScheduler();
  192. var ex = new Exception();
  193. var xs = scheduler.CreateHotObservable(
  194. OnNext(150, 1),
  195. OnError<int>(300, ex)
  196. );
  197. var res = scheduler.Start(() =>
  198. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  199. );
  200. res.Messages.AssertEqual(
  201. OnError<int>(300, ex)
  202. );
  203. xs.Subscriptions.AssertEqual(
  204. Subscribe(200, 300)
  205. );
  206. }
  207. [TestMethod]
  208. public void Sample_Periodic_Error()
  209. {
  210. var scheduler = new PeriodicTestScheduler();
  211. var ex = new Exception();
  212. var xs = scheduler.CreateHotObservable(
  213. OnNext(150, 1),
  214. OnError<int>(300, ex)
  215. );
  216. var res = scheduler.Start(() =>
  217. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  218. );
  219. res.Messages.AssertEqual(
  220. OnError<int>(300, ex)
  221. );
  222. xs.Subscriptions.AssertEqual(
  223. Subscribe(200, 300)
  224. );
  225. #if !WINDOWS
  226. scheduler.Timers.AssertEqual(
  227. new TimerRun(200, 300) { 250 }
  228. );
  229. #endif
  230. }
  231. [TestMethod]
  232. public void Sample_Never()
  233. {
  234. var scheduler = new TestScheduler();
  235. var xs = scheduler.CreateHotObservable(
  236. OnNext(150, 1)
  237. );
  238. var res = scheduler.Start(() =>
  239. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  240. );
  241. res.Messages.AssertEqual(
  242. );
  243. xs.Subscriptions.AssertEqual(
  244. Subscribe(200, 1000)
  245. );
  246. }
  247. [TestMethod]
  248. public void Sample_Periodic_Never()
  249. {
  250. var scheduler = new PeriodicTestScheduler();
  251. var xs = scheduler.CreateHotObservable(
  252. OnNext(150, 1)
  253. );
  254. var res = scheduler.Start(() =>
  255. xs.Sample(TimeSpan.FromTicks(50), scheduler)
  256. );
  257. res.Messages.AssertEqual(
  258. );
  259. xs.Subscriptions.AssertEqual(
  260. Subscribe(200, 1000)
  261. );
  262. #if !WINDOWS
  263. scheduler.Timers.AssertEqual(
  264. new TimerRun(200, 1000) { 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950 }
  265. );
  266. #endif
  267. }
  268. [TestMethod]
  269. public void Sample_DefaultScheduler_Periodic()
  270. {
  271. var res = Observable.Return(42).Sample(TimeSpan.FromMilliseconds(1)).ToEnumerable().Single();
  272. Assert.Equal(42, res);
  273. }
  274. [TestMethod]
  275. public void Sample_DefaultScheduler_PeriodicDisabled()
  276. {
  277. var res = Observable.Return(42).Sample(TimeSpan.FromMilliseconds(1), Scheduler.Default.DisableOptimizations()).ToEnumerable().Single();
  278. Assert.Equal(42, res);
  279. }
  280. [TestMethod]
  281. public void Sample_Sampler_Simple1()
  282. {
  283. var scheduler = new TestScheduler();
  284. var xs = scheduler.CreateHotObservable(
  285. OnNext(150, 1),
  286. OnNext(220, 2),
  287. OnNext(240, 3),
  288. OnNext(290, 4),
  289. OnNext(300, 5),
  290. OnNext(310, 6),
  291. OnCompleted<int>(400)
  292. );
  293. var ys = scheduler.CreateHotObservable(
  294. OnNext(150, ""),
  295. OnNext(210, "bar"),
  296. OnNext(250, "foo"),
  297. OnNext(260, "qux"),
  298. OnNext(320, "baz"),
  299. OnCompleted<string>(500)
  300. );
  301. var res = scheduler.Start(() =>
  302. xs.Sample(ys)
  303. );
  304. res.Messages.AssertEqual(
  305. OnNext(250, 3),
  306. OnNext(320, 6),
  307. OnCompleted<int>(500 /* on sampling boundaries only */)
  308. );
  309. xs.Subscriptions.AssertEqual(
  310. Subscribe(200, 400)
  311. );
  312. ys.Subscriptions.AssertEqual(
  313. Subscribe(200, 500)
  314. );
  315. }
  316. [TestMethod]
  317. public void Sample_Sampler_Simple2()
  318. {
  319. var scheduler = new TestScheduler();
  320. var xs = scheduler.CreateHotObservable(
  321. OnNext(150, 1),
  322. OnNext(220, 2),
  323. OnNext(240, 3),
  324. OnNext(290, 4),
  325. OnNext(300, 5),
  326. OnNext(310, 6),
  327. OnNext(360, 7),
  328. OnCompleted<int>(400)
  329. );
  330. var ys = scheduler.CreateHotObservable(
  331. OnNext(150, ""),
  332. OnNext(210, "bar"),
  333. OnNext(250, "foo"),
  334. OnNext(260, "qux"),
  335. OnNext(320, "baz"),
  336. OnCompleted<string>(500)
  337. );
  338. var res = scheduler.Start(() =>
  339. xs.Sample(ys)
  340. );
  341. res.Messages.AssertEqual(
  342. OnNext(250, 3),
  343. OnNext(320, 6),
  344. OnNext(500, 7),
  345. OnCompleted<int>(500 /* on sampling boundaries only */)
  346. );
  347. xs.Subscriptions.AssertEqual(
  348. Subscribe(200, 400)
  349. );
  350. ys.Subscriptions.AssertEqual(
  351. Subscribe(200, 500)
  352. );
  353. }
  354. [TestMethod]
  355. public void Sample_Sampler_Simple3()
  356. {
  357. var scheduler = new TestScheduler();
  358. var xs = scheduler.CreateHotObservable(
  359. OnNext(150, 1),
  360. OnNext(220, 2),
  361. OnNext(240, 3),
  362. OnNext(290, 4),
  363. OnCompleted<int>(300)
  364. );
  365. var ys = scheduler.CreateHotObservable(
  366. OnNext(150, ""),
  367. OnNext(210, "bar"),
  368. OnNext(250, "foo"),
  369. OnNext(260, "qux"),
  370. OnNext(320, "baz"),
  371. OnCompleted<string>(500)
  372. );
  373. var res = scheduler.Start(() =>
  374. xs.Sample(ys)
  375. );
  376. res.Messages.AssertEqual(
  377. OnNext(250, 3),
  378. OnNext(320, 4),
  379. OnCompleted<int>(320 /* on sampling boundaries only */)
  380. );
  381. xs.Subscriptions.AssertEqual(
  382. Subscribe(200, 300)
  383. );
  384. ys.Subscriptions.AssertEqual(
  385. Subscribe(200, 320)
  386. );
  387. }
  388. [TestMethod]
  389. public void Sample_Sampler_completes_first()
  390. {
  391. var scheduler = new TestScheduler();
  392. var xs = scheduler.CreateHotObservable(
  393. OnNext(150, 1),
  394. OnNext(220, 2),
  395. OnNext(240, 3),
  396. OnNext(290, 4),
  397. OnCompleted<int>(600)
  398. );
  399. var ys = scheduler.CreateHotObservable(
  400. OnNext(150, ""),
  401. OnNext(210, "bar"),
  402. OnNext(250, "foo"),
  403. OnNext(260, "qux"),
  404. OnNext(320, "baz"),
  405. OnCompleted<string>(500)
  406. );
  407. var res = scheduler.Start(() =>
  408. xs.Sample(ys)
  409. );
  410. res.Messages.AssertEqual(
  411. OnNext(250, 3),
  412. OnNext(320, 4),
  413. OnCompleted<int>(600 /* on sampling boundaries only */)
  414. );
  415. xs.Subscriptions.AssertEqual(
  416. Subscribe(200, 600)
  417. );
  418. ys.Subscriptions.AssertEqual(
  419. Subscribe(200, 500)
  420. );
  421. }
  422. [TestMethod]
  423. public void Sample_Sampler_SourceThrows()
  424. {
  425. var ex = new Exception();
  426. var scheduler = new TestScheduler();
  427. var xs = scheduler.CreateHotObservable(
  428. OnNext(150, 1),
  429. OnNext(220, 2),
  430. OnNext(240, 3),
  431. OnNext(290, 4),
  432. OnNext(300, 5),
  433. OnNext(310, 6),
  434. OnError<int>(320, ex)
  435. );
  436. var ys = scheduler.CreateHotObservable(
  437. OnNext(150, ""),
  438. OnNext(210, "bar"),
  439. OnNext(250, "foo"),
  440. OnNext(260, "qux"),
  441. OnNext(330, "baz"),
  442. OnCompleted<string>(400)
  443. );
  444. var res = scheduler.Start(() =>
  445. xs.Sample(ys)
  446. );
  447. res.Messages.AssertEqual(
  448. OnNext(250, 3),
  449. OnError<int>(320, ex)
  450. );
  451. xs.Subscriptions.AssertEqual(
  452. Subscribe(200, 320)
  453. );
  454. ys.Subscriptions.AssertEqual(
  455. Subscribe(200, 320)
  456. );
  457. }
  458. #if !NO_PERF // BREAKING CHANGE v2 > v1.x - behavior when sampler throws
  459. [TestMethod]
  460. public void Sample_Sampler_SamplerThrows()
  461. {
  462. var ex = new Exception();
  463. var scheduler = new TestScheduler();
  464. var xs = scheduler.CreateHotObservable(
  465. OnNext(150, 1),
  466. OnNext(220, 2),
  467. OnNext(240, 3),
  468. OnNext(290, 4),
  469. OnNext(300, 5),
  470. OnNext(310, 6),
  471. OnCompleted<int>(400)
  472. );
  473. var ys = scheduler.CreateHotObservable(
  474. OnNext(150, ""),
  475. OnNext(210, "bar"),
  476. OnNext(250, "foo"),
  477. OnNext(260, "qux"),
  478. OnError<string>(320, ex)
  479. );
  480. var res = scheduler.Start(() =>
  481. xs.Sample(ys)
  482. );
  483. res.Messages.AssertEqual(
  484. OnNext(250, 3),
  485. OnError<int>(320, ex)
  486. );
  487. xs.Subscriptions.AssertEqual(
  488. Subscribe(200, 320)
  489. );
  490. ys.Subscriptions.AssertEqual(
  491. Subscribe(200, 320)
  492. );
  493. }
  494. #endif
  495. }
  496. }