AggregateTest.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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.Linq;
  6. using System.Reactive.Linq;
  7. using Microsoft.Reactive.Testing;
  8. using ReactiveTests.Dummies;
  9. using Xunit;
  10. namespace ReactiveTests.Tests
  11. {
  12. public class AggregateTest : ReactiveTest
  13. {
  14. [Fact]
  15. public void Aggregate_ArgumentChecking()
  16. {
  17. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate<int, int>(default, 1, (x, y) => x + y));
  18. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate(DummyObservable<int>.Instance, 1, default));
  19. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate<int>(default, (x, y) => x + y));
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate(DummyObservable<int>.Instance, default));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate<int, int, int>(default, 1, (x, y) => x + y, x => x));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate(DummyObservable<int>.Instance, 1, default, x => x));
  23. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Aggregate<int, int, int>(DummyObservable<int>.Instance, 1, (x, y) => x + y, default));
  24. }
  25. [Fact]
  26. public void AggregateWithSeed_Empty()
  27. {
  28. var scheduler = new TestScheduler();
  29. var xs = scheduler.CreateHotObservable(
  30. OnNext(150, 1),
  31. OnCompleted<int>(250)
  32. );
  33. var res = scheduler.Start(() =>
  34. xs.Aggregate(42, (acc, x) => acc + x)
  35. );
  36. res.Messages.AssertEqual(
  37. OnNext(250, 42),
  38. OnCompleted<int>(250)
  39. );
  40. xs.Subscriptions.AssertEqual(
  41. Subscribe(200, 250)
  42. );
  43. }
  44. [Fact]
  45. public void AggregateWithSeed_Return()
  46. {
  47. var scheduler = new TestScheduler();
  48. var xs = scheduler.CreateHotObservable(
  49. OnNext(150, 1),
  50. OnNext(210, 24),
  51. OnCompleted<int>(250)
  52. );
  53. var res = scheduler.Start(() =>
  54. xs.Aggregate(42, (acc, x) => acc + x)
  55. );
  56. res.Messages.AssertEqual(
  57. OnNext(250, 42 + 24),
  58. OnCompleted<int>(250)
  59. );
  60. xs.Subscriptions.AssertEqual(
  61. Subscribe(200, 250)
  62. );
  63. }
  64. [Fact]
  65. public void AggregateWithSeed_Throw()
  66. {
  67. var ex = new Exception();
  68. var scheduler = new TestScheduler();
  69. var xs = scheduler.CreateHotObservable(
  70. OnNext(150, 1),
  71. OnError<int>(210, ex)
  72. );
  73. var res = scheduler.Start(() =>
  74. xs.Aggregate(42, (acc, x) => acc + x)
  75. );
  76. res.Messages.AssertEqual(
  77. OnError<int>(210, ex)
  78. );
  79. xs.Subscriptions.AssertEqual(
  80. Subscribe(200, 210)
  81. );
  82. }
  83. [Fact]
  84. public void AggregateWithSeed_Never()
  85. {
  86. var ex = new Exception();
  87. var scheduler = new TestScheduler();
  88. var xs = scheduler.CreateHotObservable(
  89. OnNext(150, 1)
  90. );
  91. var res = scheduler.Start(() =>
  92. xs.Aggregate(42, (acc, x) => acc + x)
  93. );
  94. res.Messages.AssertEqual(
  95. );
  96. xs.Subscriptions.AssertEqual(
  97. Subscribe(200, 1000)
  98. );
  99. }
  100. [Fact]
  101. public void AggregateWithSeed_Range()
  102. {
  103. var ex = new Exception();
  104. var scheduler = new TestScheduler();
  105. var xs = scheduler.CreateHotObservable(
  106. OnNext(150, 1),
  107. OnNext(210, 0),
  108. OnNext(220, 1),
  109. OnNext(230, 2),
  110. OnNext(240, 3),
  111. OnNext(250, 4),
  112. OnCompleted<int>(260)
  113. );
  114. var res = scheduler.Start(() =>
  115. xs.Aggregate(42, (acc, x) => acc + x)
  116. );
  117. res.Messages.AssertEqual(
  118. OnNext(260, 42 + Enumerable.Range(0, 5).Sum()),
  119. OnCompleted<int>(260)
  120. );
  121. xs.Subscriptions.AssertEqual(
  122. Subscribe(200, 260)
  123. );
  124. }
  125. [Fact]
  126. public void AggregateWithSeed_AccumulatorThrows()
  127. {
  128. var ex = new Exception();
  129. var scheduler = new TestScheduler();
  130. var xs = scheduler.CreateHotObservable(
  131. OnNext(150, 1),
  132. OnNext(210, 0),
  133. OnNext(220, 1),
  134. OnNext(230, 2),
  135. OnNext(240, 3),
  136. OnNext(250, 4),
  137. OnCompleted<int>(260)
  138. );
  139. var res = scheduler.Start(() =>
  140. xs.Aggregate(0, (acc, x) => { if (x < 3) { return acc + x; } throw ex; })
  141. );
  142. res.Messages.AssertEqual(
  143. OnError<int>(240, ex)
  144. );
  145. xs.Subscriptions.AssertEqual(
  146. Subscribe(200, 240)
  147. );
  148. }
  149. [Fact]
  150. public void AggregateWithSeedAndResult_Empty()
  151. {
  152. var scheduler = new TestScheduler();
  153. var xs = scheduler.CreateHotObservable(
  154. OnNext(150, 1),
  155. OnCompleted<int>(250)
  156. );
  157. var res = scheduler.Start(() =>
  158. xs.Aggregate(42, (acc, x) => acc + x, x => x * 5)
  159. );
  160. res.Messages.AssertEqual(
  161. OnNext(250, 42 * 5),
  162. OnCompleted<int>(250)
  163. );
  164. xs.Subscriptions.AssertEqual(
  165. Subscribe(200, 250)
  166. );
  167. }
  168. [Fact]
  169. public void AggregateWithSeedAndResult_Return()
  170. {
  171. var scheduler = new TestScheduler();
  172. var xs = scheduler.CreateHotObservable(
  173. OnNext(150, 1),
  174. OnNext(210, 24),
  175. OnCompleted<int>(250)
  176. );
  177. var res = scheduler.Start(() =>
  178. xs.Aggregate(42, (acc, x) => acc + x, x => x * 5)
  179. );
  180. res.Messages.AssertEqual(
  181. OnNext(250, (42 + 24) * 5),
  182. OnCompleted<int>(250)
  183. );
  184. xs.Subscriptions.AssertEqual(
  185. Subscribe(200, 250)
  186. );
  187. }
  188. [Fact]
  189. public void AggregateWithSeedAndResult_Throw()
  190. {
  191. var ex = new Exception();
  192. var scheduler = new TestScheduler();
  193. var xs = scheduler.CreateHotObservable(
  194. OnNext(150, 1),
  195. OnError<int>(210, ex)
  196. );
  197. var res = scheduler.Start(() =>
  198. xs.Aggregate(42, (acc, x) => acc + x, x => x * 5)
  199. );
  200. res.Messages.AssertEqual(
  201. OnError<int>(210, ex)
  202. );
  203. xs.Subscriptions.AssertEqual(
  204. Subscribe(200, 210)
  205. );
  206. }
  207. [Fact]
  208. public void AggregateWithSeedAndResult_Never()
  209. {
  210. var ex = new Exception();
  211. var scheduler = new TestScheduler();
  212. var xs = scheduler.CreateHotObservable(
  213. OnNext(150, 1)
  214. );
  215. var res = scheduler.Start(() =>
  216. xs.Aggregate(42, (acc, x) => acc + x, x => x * 5)
  217. );
  218. res.Messages.AssertEqual(
  219. );
  220. xs.Subscriptions.AssertEqual(
  221. Subscribe(200, 1000)
  222. );
  223. }
  224. [Fact]
  225. public void AggregateWithSeedAndResult_Range()
  226. {
  227. var ex = new Exception();
  228. var scheduler = new TestScheduler();
  229. var xs = scheduler.CreateHotObservable(
  230. OnNext(150, 1),
  231. OnNext(210, 0),
  232. OnNext(220, 1),
  233. OnNext(230, 2),
  234. OnNext(240, 3),
  235. OnNext(250, 4),
  236. OnCompleted<int>(260)
  237. );
  238. var res = scheduler.Start(() =>
  239. xs.Aggregate(42, (acc, x) => acc + x, x => x * 5)
  240. );
  241. res.Messages.AssertEqual(
  242. OnNext(260, (42 + Enumerable.Range(0, 5).Sum()) * 5),
  243. OnCompleted<int>(260)
  244. );
  245. xs.Subscriptions.AssertEqual(
  246. Subscribe(200, 260)
  247. );
  248. }
  249. [Fact]
  250. public void AggregateWithSeedAndResult_AccumulatorThrows()
  251. {
  252. var ex = new Exception();
  253. var scheduler = new TestScheduler();
  254. var xs = scheduler.CreateHotObservable(
  255. OnNext(150, 1),
  256. OnNext(210, 0),
  257. OnNext(220, 1),
  258. OnNext(230, 2),
  259. OnNext(240, 3),
  260. OnNext(250, 4),
  261. OnCompleted<int>(260)
  262. );
  263. var res = scheduler.Start(() =>
  264. xs.Aggregate(0, (acc, x) => { if (x < 3) { return acc + x; } throw ex; }, x => x * 5)
  265. );
  266. res.Messages.AssertEqual(
  267. OnError<int>(240, ex)
  268. );
  269. xs.Subscriptions.AssertEqual(
  270. Subscribe(200, 240)
  271. );
  272. }
  273. [Fact]
  274. public void AggregateWithSeedAndResult_ResultSelectorThrows()
  275. {
  276. var ex = new Exception();
  277. var scheduler = new TestScheduler();
  278. var xs = scheduler.CreateHotObservable(
  279. OnNext(150, 1),
  280. OnNext(210, 0),
  281. OnNext(220, 1),
  282. OnNext(230, 2),
  283. OnNext(240, 3),
  284. OnNext(250, 4),
  285. OnCompleted<int>(260)
  286. );
  287. var res = scheduler.Start(() =>
  288. xs.Aggregate<int, int, int>(0, (acc, x) => acc + x, x => { throw ex; })
  289. );
  290. res.Messages.AssertEqual(
  291. OnError<int>(260, ex)
  292. );
  293. xs.Subscriptions.AssertEqual(
  294. Subscribe(200, 260)
  295. );
  296. }
  297. [Fact]
  298. public void AggregateWithoutSeed_Empty()
  299. {
  300. var scheduler = new TestScheduler();
  301. var xs = scheduler.CreateHotObservable(
  302. OnNext(150, 1),
  303. OnCompleted<int>(250)
  304. );
  305. var res = scheduler.Start(() =>
  306. xs.Aggregate((acc, x) => acc + x)
  307. );
  308. res.Messages.AssertEqual(
  309. OnError<int>(250, e => e is InvalidOperationException)
  310. );
  311. xs.Subscriptions.AssertEqual(
  312. Subscribe(200, 250)
  313. );
  314. }
  315. [Fact]
  316. public void AggregateWithoutSeed_Return()
  317. {
  318. var scheduler = new TestScheduler();
  319. var xs = scheduler.CreateHotObservable(
  320. OnNext(150, 1),
  321. OnNext(210, 24),
  322. OnCompleted<int>(250)
  323. );
  324. var res = scheduler.Start(() =>
  325. xs.Aggregate((acc, x) => acc + x)
  326. );
  327. res.Messages.AssertEqual(
  328. OnNext(250, 24),
  329. OnCompleted<int>(250)
  330. );
  331. xs.Subscriptions.AssertEqual(
  332. Subscribe(200, 250)
  333. );
  334. }
  335. [Fact]
  336. public void AggregateWithoutSeed_Throw()
  337. {
  338. var ex = new Exception();
  339. var scheduler = new TestScheduler();
  340. var xs = scheduler.CreateHotObservable(
  341. OnNext(150, 1),
  342. OnError<int>(210, ex)
  343. );
  344. var res = scheduler.Start(() =>
  345. xs.Aggregate((acc, x) => acc + x)
  346. );
  347. res.Messages.AssertEqual(
  348. OnError<int>(210, ex)
  349. );
  350. xs.Subscriptions.AssertEqual(
  351. Subscribe(200, 210)
  352. );
  353. }
  354. [Fact]
  355. public void AggregateWithoutSeed_Never()
  356. {
  357. var scheduler = new TestScheduler();
  358. var xs = scheduler.CreateHotObservable(
  359. OnNext(150, 1)
  360. );
  361. var res = scheduler.Start(() =>
  362. xs.Aggregate((acc, x) => acc + x)
  363. );
  364. res.Messages.AssertEqual(
  365. );
  366. }
  367. [Fact]
  368. public void AggregateWithoutSeed_Range()
  369. {
  370. var scheduler = new TestScheduler();
  371. var xs = scheduler.CreateHotObservable(
  372. OnNext(150, 1),
  373. OnNext(210, 0),
  374. OnNext(220, 1),
  375. OnNext(230, 2),
  376. OnNext(240, 3),
  377. OnNext(250, 4),
  378. OnCompleted<int>(260)
  379. );
  380. var res = scheduler.Start(() =>
  381. xs.Aggregate((acc, x) => acc + x)
  382. );
  383. res.Messages.AssertEqual(
  384. OnNext(260, Enumerable.Range(0, 5).Sum()),
  385. OnCompleted<int>(260)
  386. );
  387. xs.Subscriptions.AssertEqual(
  388. Subscribe(200, 260)
  389. );
  390. }
  391. [Fact]
  392. public void AggregateWithoutSeed_AccumulatorThrows()
  393. {
  394. var ex = new Exception();
  395. var scheduler = new TestScheduler();
  396. var xs = scheduler.CreateHotObservable(
  397. OnNext(150, 1),
  398. OnNext(210, 0),
  399. OnNext(220, 1),
  400. OnNext(230, 2),
  401. OnNext(240, 3),
  402. OnNext(250, 4),
  403. OnCompleted<int>(260)
  404. );
  405. var res = scheduler.Start(() =>
  406. xs.Aggregate((acc, x) => { if (x < 3) { return acc + x; } throw ex; })
  407. );
  408. res.Messages.AssertEqual(
  409. OnError<int>(240, ex)
  410. );
  411. xs.Subscriptions.AssertEqual(
  412. Subscribe(200, 240)
  413. );
  414. }
  415. }
  416. }