DistinctUntilChangedTest.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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.Reactive.Linq;
  7. using Microsoft.Reactive.Testing;
  8. using Xunit;
  9. namespace ReactiveTests.Tests
  10. {
  11. public class DistinctUntilChangedTest : ReactiveTest
  12. {
  13. [Fact]
  14. public void DistinctUntilChanged_ArgumentChecking()
  15. {
  16. var someObservable = Observable.Empty<int>();
  17. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged<int>(null));
  18. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged(null, EqualityComparer<int>.Default));
  19. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged(someObservable, null));
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged<int, int>(null, _ => _));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged<int, int>(someObservable, null));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged(someObservable, _ => _, null));
  23. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged<int, int>(null, _ => _, EqualityComparer<int>.Default));
  24. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.DistinctUntilChanged(someObservable, null, EqualityComparer<int>.Default));
  25. }
  26. [Fact]
  27. public void DistinctUntilChanged_Never()
  28. {
  29. var scheduler = new TestScheduler();
  30. var xs = Observable.Never<int>();
  31. var res = scheduler.Start(() =>
  32. xs.DistinctUntilChanged()
  33. );
  34. res.Messages.AssertEqual(
  35. );
  36. }
  37. [Fact]
  38. public void DistinctUntilChanged_Empty()
  39. {
  40. var scheduler = new TestScheduler();
  41. var xs = scheduler.CreateHotObservable(
  42. OnNext(150, 1),
  43. OnCompleted<int>(250)
  44. );
  45. var res = scheduler.Start(() =>
  46. xs.DistinctUntilChanged()
  47. );
  48. res.Messages.AssertEqual(
  49. OnCompleted<int>(250)
  50. );
  51. xs.Subscriptions.AssertEqual(
  52. Subscribe(200, 250)
  53. );
  54. }
  55. [Fact]
  56. public void DistinctUntilChanged_Return()
  57. {
  58. var scheduler = new TestScheduler();
  59. var xs = scheduler.CreateHotObservable(
  60. OnNext(150, 1),
  61. OnNext(220, 2),
  62. OnCompleted<int>(250)
  63. );
  64. var res = scheduler.Start(() =>
  65. xs.DistinctUntilChanged()
  66. );
  67. res.Messages.AssertEqual(
  68. OnNext(220, 2),
  69. OnCompleted<int>(250)
  70. );
  71. xs.Subscriptions.AssertEqual(
  72. Subscribe(200, 250)
  73. );
  74. }
  75. [Fact]
  76. public void DistinctUntilChanged_Throw()
  77. {
  78. var scheduler = new TestScheduler();
  79. var ex = new Exception();
  80. var xs = scheduler.CreateHotObservable(
  81. OnNext(150, 1),
  82. OnError<int>(250, ex)
  83. );
  84. var res = scheduler.Start(() =>
  85. xs.DistinctUntilChanged()
  86. );
  87. res.Messages.AssertEqual(
  88. OnError<int>(250, ex)
  89. );
  90. xs.Subscriptions.AssertEqual(
  91. Subscribe(200, 250)
  92. );
  93. }
  94. [Fact]
  95. public void DistinctUntilChanged_AllChanges()
  96. {
  97. var scheduler = new TestScheduler();
  98. var xs = scheduler.CreateHotObservable(
  99. OnNext(150, 1),
  100. OnNext(210, 2),
  101. OnNext(220, 3),
  102. OnNext(230, 4),
  103. OnNext(240, 5),
  104. OnCompleted<int>(250)
  105. );
  106. var res = scheduler.Start(() =>
  107. xs.DistinctUntilChanged()
  108. );
  109. res.Messages.AssertEqual(
  110. OnNext(210, 2),
  111. OnNext(220, 3),
  112. OnNext(230, 4),
  113. OnNext(240, 5),
  114. OnCompleted<int>(250)
  115. );
  116. xs.Subscriptions.AssertEqual(
  117. Subscribe(200, 250)
  118. );
  119. }
  120. [Fact]
  121. public void DistinctUntilChanged_AllSame()
  122. {
  123. var scheduler = new TestScheduler();
  124. var xs = scheduler.CreateHotObservable(
  125. OnNext(150, 1),
  126. OnNext(210, 2),
  127. OnNext(220, 2),
  128. OnNext(230, 2),
  129. OnNext(240, 2),
  130. OnCompleted<int>(250)
  131. );
  132. var res = scheduler.Start(() =>
  133. xs.DistinctUntilChanged()
  134. );
  135. res.Messages.AssertEqual(
  136. OnNext(210, 2),
  137. OnCompleted<int>(250)
  138. );
  139. xs.Subscriptions.AssertEqual(
  140. Subscribe(200, 250)
  141. );
  142. }
  143. [Fact]
  144. public void DistinctUntilChanged_SomeChanges()
  145. {
  146. var scheduler = new TestScheduler();
  147. var xs = scheduler.CreateHotObservable(
  148. OnNext(150, 1),
  149. OnNext(210, 2), //*
  150. OnNext(215, 3), //*
  151. OnNext(220, 3),
  152. OnNext(225, 2), //*
  153. OnNext(230, 2),
  154. OnNext(230, 1), //*
  155. OnNext(240, 2), //*
  156. OnCompleted<int>(250)
  157. );
  158. var res = scheduler.Start(() =>
  159. xs.DistinctUntilChanged()
  160. );
  161. res.Messages.AssertEqual(
  162. OnNext(210, 2),
  163. OnNext(215, 3),
  164. OnNext(225, 2),
  165. OnNext(230, 1),
  166. OnNext(240, 2),
  167. OnCompleted<int>(250)
  168. );
  169. xs.Subscriptions.AssertEqual(
  170. Subscribe(200, 250)
  171. );
  172. }
  173. [Fact]
  174. public void DistinctUntilChanged_Comparer_AllEqual()
  175. {
  176. var scheduler = new TestScheduler();
  177. var xs = scheduler.CreateHotObservable(
  178. OnNext(150, 1),
  179. OnNext(210, 2),
  180. OnNext(220, 3),
  181. OnNext(230, 4),
  182. OnNext(240, 5),
  183. OnCompleted<int>(250)
  184. );
  185. var res = scheduler.Start(() =>
  186. xs.DistinctUntilChanged(new FuncComparer<int>((x, y) => true))
  187. );
  188. res.Messages.AssertEqual(
  189. OnNext(210, 2),
  190. OnCompleted<int>(250)
  191. );
  192. xs.Subscriptions.AssertEqual(
  193. Subscribe(200, 250)
  194. );
  195. }
  196. [Fact]
  197. public void DistinctUntilChanged_Comparer_AllDifferent()
  198. {
  199. var scheduler = new TestScheduler();
  200. var xs = scheduler.CreateHotObservable(
  201. OnNext(150, 1),
  202. OnNext(210, 2),
  203. OnNext(220, 2),
  204. OnNext(230, 2),
  205. OnNext(240, 2),
  206. OnCompleted<int>(250)
  207. );
  208. var res = scheduler.Start(() =>
  209. xs.DistinctUntilChanged(new FuncComparer<int>((x, y) => false))
  210. );
  211. res.Messages.AssertEqual(
  212. OnNext(210, 2),
  213. OnNext(220, 2),
  214. OnNext(230, 2),
  215. OnNext(240, 2),
  216. OnCompleted<int>(250)
  217. );
  218. xs.Subscriptions.AssertEqual(
  219. Subscribe(200, 250)
  220. );
  221. }
  222. [Fact]
  223. public void DistinctUntilChanged_KeySelector_Div2()
  224. {
  225. var scheduler = new TestScheduler();
  226. var xs = scheduler.CreateHotObservable(
  227. OnNext(150, 1),
  228. OnNext(210, 2), //*
  229. OnNext(220, 4),
  230. OnNext(230, 3), //*
  231. OnNext(240, 5),
  232. OnCompleted<int>(250)
  233. );
  234. var res = scheduler.Start(() =>
  235. xs.DistinctUntilChanged(x => x % 2)
  236. );
  237. res.Messages.AssertEqual(
  238. OnNext(210, 2),
  239. OnNext(230, 3),
  240. OnCompleted<int>(250)
  241. );
  242. xs.Subscriptions.AssertEqual(
  243. Subscribe(200, 250)
  244. );
  245. }
  246. private class FuncComparer<T> : IEqualityComparer<T>
  247. {
  248. private readonly Func<T, T, bool> _equals;
  249. public FuncComparer(Func<T, T, bool> equals)
  250. {
  251. _equals = equals;
  252. }
  253. public bool Equals(T x, T y)
  254. {
  255. return _equals(x, y);
  256. }
  257. public int GetHashCode(T obj)
  258. {
  259. return 0;
  260. }
  261. }
  262. [Fact]
  263. public void DistinctUntilChanged_KeySelectorThrows()
  264. {
  265. var ex = new Exception();
  266. var scheduler = new TestScheduler();
  267. var xs = scheduler.CreateHotObservable(
  268. OnNext(150, 1),
  269. OnNext(210, 2),
  270. OnCompleted<int>(250)
  271. );
  272. var res = scheduler.Start(() =>
  273. xs.DistinctUntilChanged(new Func<int, int>(x => { throw ex; }))
  274. );
  275. res.Messages.AssertEqual(
  276. OnError<int>(210, ex)
  277. );
  278. }
  279. [Fact]
  280. public void DistinctUntilChanged_ComparerThrows()
  281. {
  282. var ex = new Exception();
  283. var scheduler = new TestScheduler();
  284. var xs = scheduler.CreateHotObservable(
  285. OnNext(150, 1),
  286. OnNext(210, 2),
  287. OnNext(220, 3),
  288. OnCompleted<int>(250)
  289. );
  290. var res = scheduler.Start(() =>
  291. xs.DistinctUntilChanged(new ThrowComparer<int>(ex))
  292. );
  293. res.Messages.AssertEqual(
  294. OnNext(210, 2),
  295. OnError<int>(220, ex)
  296. );
  297. }
  298. private class ThrowComparer<T> : IEqualityComparer<T>
  299. {
  300. private readonly Exception _ex;
  301. public ThrowComparer(Exception ex)
  302. {
  303. _ex = ex;
  304. }
  305. public bool Equals(T x, T y)
  306. {
  307. throw _ex;
  308. }
  309. public int GetHashCode(T obj)
  310. {
  311. return 0;
  312. }
  313. }
  314. [Fact]
  315. public void DistinctUntilChanged_KeySelector_Comparer()
  316. {
  317. var scheduler = new TestScheduler();
  318. var xs = scheduler.CreateHotObservable(
  319. OnNext(150, 1),
  320. OnNext(210, 2), // * key = 1 % 3 = 1
  321. OnNext(220, 8), // key = 4 % 3 = 1 same
  322. OnNext(230, 2), // key = 1 % 3 = 1 same
  323. OnNext(240, 5), // * key = 2 % 3 = 2
  324. OnCompleted<int>(250)
  325. );
  326. var res = scheduler.Start(() =>
  327. xs.DistinctUntilChanged(x => x / 2, new FuncComparer<int>((x, y) => x % 3 == y % 3))
  328. );
  329. res.Messages.AssertEqual(
  330. OnNext(210, 2),
  331. OnNext(240, 5),
  332. OnCompleted<int>(250)
  333. );
  334. xs.Subscriptions.AssertEqual(
  335. Subscribe(200, 250)
  336. );
  337. }
  338. }
  339. }