DistinctTest.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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.Collections.Generic;
  6. using System.Linq;
  7. using System.Reactive.Linq;
  8. using Microsoft.Reactive.Testing;
  9. using ReactiveTests.Dummies;
  10. using Microsoft.VisualStudio.TestTools.UnitTesting;
  11. namespace ReactiveTests.Tests
  12. {
  13. [TestClass]
  14. public class DistinctTest : ReactiveTest
  15. {
  16. [TestMethod]
  17. public void Distinct_ArgumentChecking()
  18. {
  19. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(default(IObservable<int>)));
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(default, EqualityComparer<int>.Default));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(DummyObservable<int>.Instance, default(EqualityComparer<int>)));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(default(IObservable<int>), x => x));
  23. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(DummyObservable<int>.Instance, default(Func<int, int>)));
  24. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(default(IObservable<int>), x => x, EqualityComparer<int>.Default));
  25. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(DummyObservable<int>.Instance, default, EqualityComparer<int>.Default));
  26. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Distinct(DummyObservable<int>.Instance, x => x, default(EqualityComparer<int>)));
  27. }
  28. [TestMethod]
  29. public void Distinct_DefaultComparer_AllDistinct()
  30. {
  31. var scheduler = new TestScheduler();
  32. var xs = scheduler.CreateHotObservable(
  33. OnNext(280, 4),
  34. OnNext(300, 2),
  35. OnNext(350, 1),
  36. OnNext(380, 3),
  37. OnNext(400, 5),
  38. OnCompleted<int>(420)
  39. );
  40. var res = scheduler.Start(() =>
  41. xs.Distinct()
  42. );
  43. res.Messages.AssertEqual(
  44. OnNext(280, 4),
  45. OnNext(300, 2),
  46. OnNext(350, 1),
  47. OnNext(380, 3),
  48. OnNext(400, 5),
  49. OnCompleted<int>(420)
  50. );
  51. xs.Subscriptions.AssertEqual(
  52. Subscribe(200, 420)
  53. );
  54. }
  55. [TestMethod]
  56. public void Distinct_DefaultComparer_SomeDuplicates()
  57. {
  58. var scheduler = new TestScheduler();
  59. var xs = scheduler.CreateHotObservable(
  60. OnNext(280, 4),
  61. OnNext(300, 2),
  62. OnNext(350, 2),
  63. OnNext(380, 3),
  64. OnNext(400, 4),
  65. OnCompleted<int>(420)
  66. );
  67. var res = scheduler.Start(() =>
  68. xs.Distinct()
  69. );
  70. res.Messages.AssertEqual(
  71. OnNext(280, 4),
  72. OnNext(300, 2),
  73. OnNext(380, 3),
  74. OnCompleted<int>(420)
  75. );
  76. xs.Subscriptions.AssertEqual(
  77. Subscribe(200, 420)
  78. );
  79. }
  80. [TestMethod]
  81. public void Distinct_CustomComparer_AllDistinct()
  82. {
  83. var scheduler = new TestScheduler();
  84. var xs = scheduler.CreateHotObservable(
  85. OnNext(280, 4),
  86. OnNext(300, 2),
  87. OnNext(350, 1),
  88. OnNext(380, 3),
  89. OnNext(400, 5),
  90. OnCompleted<int>(420)
  91. );
  92. var res = scheduler.Start(() =>
  93. xs.Distinct(new ModComparer(10))
  94. );
  95. res.Messages.AssertEqual(
  96. OnNext(280, 4),
  97. OnNext(300, 2),
  98. OnNext(350, 1),
  99. OnNext(380, 3),
  100. OnNext(400, 5),
  101. OnCompleted<int>(420)
  102. );
  103. xs.Subscriptions.AssertEqual(
  104. Subscribe(200, 420)
  105. );
  106. }
  107. [TestMethod]
  108. public void Distinct_CustomComparer_SomeDuplicates()
  109. {
  110. var scheduler = new TestScheduler();
  111. var xs = scheduler.CreateHotObservable(
  112. OnNext(280, 4),
  113. OnNext(300, 2),
  114. OnNext(350, 12),
  115. OnNext(380, 3),
  116. OnNext(400, 24),
  117. OnCompleted<int>(420)
  118. );
  119. var res = scheduler.Start(() =>
  120. xs.Distinct(new ModComparer(10))
  121. );
  122. res.Messages.AssertEqual(
  123. OnNext(280, 4),
  124. OnNext(300, 2),
  125. OnNext(380, 3),
  126. OnCompleted<int>(420)
  127. );
  128. xs.Subscriptions.AssertEqual(
  129. Subscribe(200, 420)
  130. );
  131. }
  132. private class ModComparer : IEqualityComparer<int>
  133. {
  134. private readonly int _mod;
  135. public ModComparer(int mod)
  136. {
  137. _mod = mod;
  138. }
  139. public bool Equals(int x, int y)
  140. {
  141. return EqualityComparer<int>.Default.Equals(x % _mod, y % _mod);
  142. }
  143. public int GetHashCode(int obj)
  144. {
  145. return EqualityComparer<int>.Default.GetHashCode(obj % _mod);
  146. }
  147. }
  148. [TestMethod]
  149. public void Distinct_KeySelector_DefaultComparer_AllDistinct()
  150. {
  151. var scheduler = new TestScheduler();
  152. var xs = scheduler.CreateHotObservable(
  153. OnNext(280, 8),
  154. OnNext(300, 4),
  155. OnNext(350, 2),
  156. OnNext(380, 6),
  157. OnNext(400, 10),
  158. OnCompleted<int>(420)
  159. );
  160. var res = scheduler.Start(() =>
  161. xs.Distinct(x => x / 2)
  162. );
  163. res.Messages.AssertEqual(
  164. OnNext(280, 8),
  165. OnNext(300, 4),
  166. OnNext(350, 2),
  167. OnNext(380, 6),
  168. OnNext(400, 10),
  169. OnCompleted<int>(420)
  170. );
  171. xs.Subscriptions.AssertEqual(
  172. Subscribe(200, 420)
  173. );
  174. }
  175. [TestMethod]
  176. public void Distinct_KeySelector_DefaultComparer_SomeDuplicates()
  177. {
  178. var scheduler = new TestScheduler();
  179. var xs = scheduler.CreateHotObservable(
  180. OnNext(280, 4),
  181. OnNext(300, 2),
  182. OnNext(350, 3),
  183. OnNext(380, 7),
  184. OnNext(400, 5),
  185. OnCompleted<int>(420)
  186. );
  187. var res = scheduler.Start(() =>
  188. xs.Distinct(x => x / 2)
  189. );
  190. res.Messages.AssertEqual(
  191. OnNext(280, 4),
  192. OnNext(300, 2),
  193. OnNext(380, 7),
  194. OnCompleted<int>(420)
  195. );
  196. xs.Subscriptions.AssertEqual(
  197. Subscribe(200, 420)
  198. );
  199. }
  200. [TestMethod]
  201. public void Distinct_KeySelector_CustomComparer_AllDistinct()
  202. {
  203. var scheduler = new TestScheduler();
  204. var xs = scheduler.CreateHotObservable(
  205. OnNext(280, 8),
  206. OnNext(300, 4),
  207. OnNext(350, 2),
  208. OnNext(380, 6),
  209. OnNext(400, 10),
  210. OnCompleted<int>(420)
  211. );
  212. var res = scheduler.Start(() =>
  213. xs.Distinct(x => x / 2, new ModComparer(10))
  214. );
  215. res.Messages.AssertEqual(
  216. OnNext(280, 8),
  217. OnNext(300, 4),
  218. OnNext(350, 2),
  219. OnNext(380, 6),
  220. OnNext(400, 10),
  221. OnCompleted<int>(420)
  222. );
  223. xs.Subscriptions.AssertEqual(
  224. Subscribe(200, 420)
  225. );
  226. }
  227. [TestMethod]
  228. public void Distinct_KeySelector_CustomComparer_SomeDuplicates()
  229. {
  230. var scheduler = new TestScheduler();
  231. var xs = scheduler.CreateHotObservable(
  232. OnNext(280, 8),
  233. OnNext(300, 4),
  234. OnNext(350, 2),
  235. OnNext(380, 6),
  236. OnNext(400, 10),
  237. OnCompleted<int>(420)
  238. );
  239. var res = scheduler.Start(() =>
  240. xs.Distinct(x => x / 2, new ModComparer(3))
  241. );
  242. res.Messages.AssertEqual(
  243. OnNext(280, 8),
  244. OnNext(300, 4),
  245. OnNext(380, 6),
  246. OnCompleted<int>(420)
  247. );
  248. xs.Subscriptions.AssertEqual(
  249. Subscribe(200, 420)
  250. );
  251. }
  252. [TestMethod]
  253. public void Distinct_KeySelector_Throws()
  254. {
  255. var scheduler = new TestScheduler();
  256. var xs = scheduler.CreateHotObservable(
  257. OnNext(280, 3),
  258. OnNext(300, 2),
  259. OnNext(350, 1),
  260. OnNext(380, 0),
  261. OnNext(400, 4),
  262. OnCompleted<int>(420)
  263. );
  264. var ex = new Exception();
  265. var res = scheduler.Start(() =>
  266. xs.Distinct(x => { if (x == 0) { throw ex; } return x / 2; })
  267. );
  268. res.Messages.AssertEqual(
  269. OnNext(280, 3),
  270. OnNext(350, 1),
  271. OnError<int>(380, ex)
  272. );
  273. xs.Subscriptions.AssertEqual(
  274. Subscribe(200, 380)
  275. );
  276. }
  277. [TestMethod]
  278. public void Distinct_CustomComparer_Throws()
  279. {
  280. var scheduler = new TestScheduler();
  281. var xs = scheduler.CreateHotObservable(
  282. OnNext(280, 1),
  283. OnNext(300, 2),
  284. OnNext(350, 3),
  285. OnNext(380, 4),
  286. OnNext(400, 5),
  287. OnCompleted<int>(420)
  288. );
  289. var ex = new Exception();
  290. var res = scheduler.Start(() =>
  291. xs.Distinct(new ThrowComparer(4, ex))
  292. );
  293. res.Messages.AssertEqual(
  294. OnNext(280, 1),
  295. OnNext(300, 2),
  296. OnNext(350, 3),
  297. OnError<int>(380, ex)
  298. );
  299. xs.Subscriptions.AssertEqual(
  300. Subscribe(200, 380)
  301. );
  302. }
  303. private class ThrowComparer : IEqualityComparer<int>
  304. {
  305. private readonly int _err;
  306. private readonly Exception _ex;
  307. public ThrowComparer(int err, Exception ex)
  308. {
  309. _err = err;
  310. _ex = ex;
  311. }
  312. public bool Equals(int x, int y)
  313. {
  314. return EqualityComparer<int>.Default.Equals(x, y);
  315. }
  316. public int GetHashCode(int obj)
  317. {
  318. if (obj == _err)
  319. {
  320. throw _ex;
  321. }
  322. return EqualityComparer<int>.Default.GetHashCode(obj);
  323. }
  324. }
  325. [TestMethod]
  326. public void Distinct_Throw()
  327. {
  328. var scheduler = new TestScheduler();
  329. var ex = new Exception();
  330. var xs = scheduler.CreateHotObservable(
  331. OnNext(280, 1),
  332. OnNext(300, 2),
  333. OnNext(350, 3),
  334. OnError<int>(380, ex)
  335. );
  336. var res = scheduler.Start(() =>
  337. xs.Distinct()
  338. );
  339. res.Messages.AssertEqual(
  340. OnNext(280, 1),
  341. OnNext(300, 2),
  342. OnNext(350, 3),
  343. OnError<int>(380, ex)
  344. );
  345. xs.Subscriptions.AssertEqual(
  346. Subscribe(200, 380)
  347. );
  348. }
  349. [TestMethod]
  350. public void Distinct_Null()
  351. {
  352. var scheduler = new TestScheduler();
  353. var xs = scheduler.CreateHotObservable(
  354. OnNext(220, "bar"),
  355. OnNext(240, default(string)),
  356. OnNext(260, "bar"),
  357. OnNext(280, "foo"),
  358. OnNext(300, default(string)),
  359. OnCompleted<string>(400)
  360. );
  361. var res = scheduler.Start(() =>
  362. xs.Distinct()
  363. );
  364. res.Messages.AssertEqual(
  365. OnNext(220, "bar"),
  366. OnNext(240, default(string)),
  367. OnNext(280, "foo"),
  368. OnCompleted<string>(400)
  369. );
  370. xs.Subscriptions.AssertEqual(
  371. Subscribe(200, 400)
  372. );
  373. }
  374. }
  375. }