MinByTest.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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.Linq;
  8. using Microsoft.Reactive.Testing;
  9. using ReactiveTests.Dummies;
  10. using Xunit;
  11. namespace ReactiveTests.Tests
  12. {
  13. public class MinByTest : ReactiveTest
  14. {
  15. [Fact]
  16. public void MinBy_ArgumentChecking()
  17. {
  18. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.MinBy(default(IObservable<int>), x => x));
  19. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.MinBy(DummyObservable<int>.Instance, default(Func<int, int>)));
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.MinBy(default(IObservable<int>), x => x, Comparer<int>.Default));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.MinBy(DummyObservable<int>.Instance, default, Comparer<int>.Default));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.MinBy(DummyObservable<int>.Instance, x => x, null));
  23. }
  24. [Fact]
  25. public void MinBy_Empty()
  26. {
  27. var scheduler = new TestScheduler();
  28. var xs = scheduler.CreateHotObservable(
  29. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  30. OnCompleted<KeyValuePair<int, string>>(250)
  31. );
  32. var res = scheduler.Start(() =>
  33. xs.MinBy(x => x.Key)
  34. );
  35. res.Messages.AssertEqual(
  36. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.Count == 0),
  37. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  38. );
  39. xs.Subscriptions.AssertEqual(
  40. Subscribe(200, 250)
  41. );
  42. }
  43. [Fact]
  44. public void MinBy_Return()
  45. {
  46. var scheduler = new TestScheduler();
  47. var xs = scheduler.CreateHotObservable(
  48. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  49. OnNext(210, new KeyValuePair<int, string>(2, "a")),
  50. OnCompleted<KeyValuePair<int, string>>(250)
  51. );
  52. var res = scheduler.Start(() =>
  53. xs.MinBy(x => x.Key)
  54. );
  55. res.Messages.AssertEqual(
  56. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.SequenceEqual(new[] {
  57. new KeyValuePair<int, string>(2, "a"),
  58. })),
  59. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  60. );
  61. xs.Subscriptions.AssertEqual(
  62. Subscribe(200, 250)
  63. );
  64. }
  65. [Fact]
  66. public void MinBy_Some()
  67. {
  68. var scheduler = new TestScheduler();
  69. var xs = scheduler.CreateHotObservable(
  70. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  71. OnNext(210, new KeyValuePair<int, string>(3, "b")),
  72. OnNext(220, new KeyValuePair<int, string>(2, "c")),
  73. OnNext(230, new KeyValuePair<int, string>(4, "a")),
  74. OnCompleted<KeyValuePair<int, string>>(250)
  75. );
  76. var res = scheduler.Start(() =>
  77. xs.MinBy(x => x.Key)
  78. );
  79. res.Messages.AssertEqual(
  80. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.SequenceEqual(new[] {
  81. new KeyValuePair<int, string>(2, "c"),
  82. })),
  83. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  84. );
  85. xs.Subscriptions.AssertEqual(
  86. Subscribe(200, 250)
  87. );
  88. }
  89. [Fact]
  90. public void MinBy_Multiple()
  91. {
  92. var scheduler = new TestScheduler();
  93. var xs = scheduler.CreateHotObservable(
  94. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  95. OnNext(210, new KeyValuePair<int, string>(3, "b")),
  96. OnNext(215, new KeyValuePair<int, string>(2, "d")),
  97. OnNext(220, new KeyValuePair<int, string>(3, "c")),
  98. OnNext(225, new KeyValuePair<int, string>(2, "y")),
  99. OnNext(230, new KeyValuePair<int, string>(4, "a")),
  100. OnNext(235, new KeyValuePair<int, string>(4, "r")),
  101. OnCompleted<KeyValuePair<int, string>>(250)
  102. );
  103. var res = scheduler.Start(() =>
  104. xs.MinBy(x => x.Key)
  105. );
  106. res.Messages.AssertEqual(
  107. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.SequenceEqual(new[] {
  108. new KeyValuePair<int, string>(2, "d"),
  109. new KeyValuePair<int, string>(2, "y"),
  110. })),
  111. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  112. );
  113. xs.Subscriptions.AssertEqual(
  114. Subscribe(200, 250)
  115. );
  116. }
  117. [Fact]
  118. public void MinBy_Throw()
  119. {
  120. var ex = new Exception();
  121. var scheduler = new TestScheduler();
  122. var xs = scheduler.CreateHotObservable(
  123. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  124. OnError<KeyValuePair<int, string>>(210, ex)
  125. );
  126. var res = scheduler.Start(() =>
  127. xs.MinBy(x => x.Key)
  128. );
  129. res.Messages.AssertEqual(
  130. OnError<IList<KeyValuePair<int, string>>>(210, ex)
  131. );
  132. xs.Subscriptions.AssertEqual(
  133. Subscribe(200, 210)
  134. );
  135. }
  136. [Fact]
  137. public void MinBy_Never()
  138. {
  139. var ex = new Exception();
  140. var scheduler = new TestScheduler();
  141. var xs = scheduler.CreateHotObservable(
  142. OnNext(150, new KeyValuePair<int, string>(1, "z"))
  143. );
  144. var res = scheduler.Start(() =>
  145. xs.MinBy(x => x.Key)
  146. );
  147. res.Messages.AssertEqual(
  148. );
  149. xs.Subscriptions.AssertEqual(
  150. Subscribe(200, 1000)
  151. );
  152. }
  153. [Fact]
  154. public void MinBy_Comparer_Empty()
  155. {
  156. var scheduler = new TestScheduler();
  157. var xs = scheduler.CreateHotObservable(
  158. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  159. OnCompleted<KeyValuePair<int, string>>(250)
  160. );
  161. var res = scheduler.Start(() =>
  162. xs.MinBy(x => x.Key, new ReverseComparer<int>(Comparer<int>.Default))
  163. );
  164. res.Messages.AssertEqual(
  165. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.Count == 0),
  166. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  167. );
  168. xs.Subscriptions.AssertEqual(
  169. Subscribe(200, 250)
  170. );
  171. }
  172. [Fact]
  173. public void MinBy_Comparer_Return()
  174. {
  175. var scheduler = new TestScheduler();
  176. var xs = scheduler.CreateHotObservable(
  177. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  178. OnNext(210, new KeyValuePair<int, string>(2, "a")),
  179. OnCompleted<KeyValuePair<int, string>>(250)
  180. );
  181. var res = scheduler.Start(() =>
  182. xs.MinBy(x => x.Key, new ReverseComparer<int>(Comparer<int>.Default))
  183. );
  184. res.Messages.AssertEqual(
  185. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.SequenceEqual(new[] {
  186. new KeyValuePair<int, string>(2, "a"),
  187. })),
  188. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  189. );
  190. xs.Subscriptions.AssertEqual(
  191. Subscribe(200, 250)
  192. );
  193. }
  194. [Fact]
  195. public void MinBy_Comparer_Some()
  196. {
  197. var scheduler = new TestScheduler();
  198. var xs = scheduler.CreateHotObservable(
  199. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  200. OnNext(210, new KeyValuePair<int, string>(3, "b")),
  201. OnNext(220, new KeyValuePair<int, string>(20, "c")),
  202. OnNext(230, new KeyValuePair<int, string>(4, "a")),
  203. OnCompleted<KeyValuePair<int, string>>(250)
  204. );
  205. var res = scheduler.Start(() =>
  206. xs.MinBy(x => x.Key, new ReverseComparer<int>(Comparer<int>.Default))
  207. );
  208. res.Messages.AssertEqual(
  209. OnNext<IList<KeyValuePair<int, string>>>(250, x => x.SequenceEqual(new[] {
  210. new KeyValuePair<int, string>(20, "c"),
  211. })),
  212. OnCompleted<IList<KeyValuePair<int, string>>>(250)
  213. );
  214. xs.Subscriptions.AssertEqual(
  215. Subscribe(200, 250)
  216. );
  217. }
  218. [Fact]
  219. public void MinBy_Comparer_Throw()
  220. {
  221. var ex = new Exception();
  222. var scheduler = new TestScheduler();
  223. var xs = scheduler.CreateHotObservable(
  224. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  225. OnError<KeyValuePair<int, string>>(210, ex)
  226. );
  227. var res = scheduler.Start(() =>
  228. xs.MinBy(x => x.Key, new ReverseComparer<int>(Comparer<int>.Default))
  229. );
  230. res.Messages.AssertEqual(
  231. OnError<IList<KeyValuePair<int, string>>>(210, ex)
  232. );
  233. xs.Subscriptions.AssertEqual(
  234. Subscribe(200, 210)
  235. );
  236. }
  237. [Fact]
  238. public void MinBy_Comparer_Never()
  239. {
  240. var ex = new Exception();
  241. var scheduler = new TestScheduler();
  242. var xs = scheduler.CreateHotObservable(
  243. OnNext(150, new KeyValuePair<int, string>(1, "z"))
  244. );
  245. var res = scheduler.Start(() =>
  246. xs.MinBy(x => x.Key, new ReverseComparer<int>(Comparer<int>.Default))
  247. );
  248. res.Messages.AssertEqual(
  249. );
  250. xs.Subscriptions.AssertEqual(
  251. Subscribe(200, 1000)
  252. );
  253. }
  254. [Fact]
  255. public void MinBy_SelectorThrows()
  256. {
  257. var ex = new Exception();
  258. var scheduler = new TestScheduler();
  259. var xs = scheduler.CreateHotObservable(
  260. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  261. OnNext(210, new KeyValuePair<int, string>(3, "b")),
  262. OnNext(220, new KeyValuePair<int, string>(2, "c")),
  263. OnNext(230, new KeyValuePair<int, string>(4, "a")),
  264. OnCompleted<KeyValuePair<int, string>>(250)
  265. );
  266. var res = scheduler.Start(() =>
  267. xs.MinBy<KeyValuePair<int, string>, int>(x => { throw ex; })
  268. );
  269. res.Messages.AssertEqual(
  270. OnError<IList<KeyValuePair<int, string>>>(210, ex)
  271. );
  272. xs.Subscriptions.AssertEqual(
  273. Subscribe(200, 210)
  274. );
  275. }
  276. [Fact]
  277. public void MinBy_ComparerThrows()
  278. {
  279. var ex = new Exception();
  280. var scheduler = new TestScheduler();
  281. var xs = scheduler.CreateHotObservable(
  282. OnNext(150, new KeyValuePair<int, string>(1, "z")),
  283. OnNext(210, new KeyValuePair<int, string>(3, "b")),
  284. OnNext(220, new KeyValuePair<int, string>(2, "c")),
  285. OnNext(230, new KeyValuePair<int, string>(4, "a")),
  286. OnCompleted<KeyValuePair<int, string>>(250)
  287. );
  288. var res = scheduler.Start(() =>
  289. xs.MinBy(x => x.Key, new ThrowingComparer<int>(ex))
  290. );
  291. res.Messages.AssertEqual(
  292. OnError<IList<KeyValuePair<int, string>>>(220, ex)
  293. );
  294. xs.Subscriptions.AssertEqual(
  295. Subscribe(200, 220)
  296. );
  297. }
  298. private class ReverseComparer<T> : IComparer<T>
  299. {
  300. private IComparer<T> _comparer;
  301. public ReverseComparer(IComparer<T> comparer)
  302. {
  303. _comparer = comparer;
  304. }
  305. public int Compare(T x, T y)
  306. {
  307. return -_comparer.Compare(x, y);
  308. }
  309. }
  310. private class ThrowingComparer<T> : IComparer<T>
  311. {
  312. private readonly Exception _ex;
  313. public ThrowingComparer(Exception ex)
  314. {
  315. _ex = ex;
  316. }
  317. public int Compare(T x, T y)
  318. {
  319. throw _ex;
  320. }
  321. }
  322. }
  323. }