SingleAsyncTest.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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.Reactive.Linq;
  6. using System.Reactive.Threading.Tasks;
  7. using System.Threading.Tasks;
  8. using Microsoft.Reactive.Testing;
  9. using ReactiveTests.Dummies;
  10. using Microsoft.VisualStudio.TestTools.UnitTesting;
  11. using Assert = Xunit.Assert;
  12. namespace ReactiveTests.Tests
  13. {
  14. [TestClass]
  15. public class SingleAsyncTest : ReactiveTest
  16. {
  17. [TestMethod]
  18. public void SingleAsync_ArgumentChecking()
  19. {
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.SingleAsync(default(IObservable<int>)));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.SingleAsync(default(IObservable<int>), _ => true));
  22. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.SingleAsync(DummyObservable<int>.Instance, default));
  23. }
  24. [TestMethod]
  25. public void SingleAsync_Empty()
  26. {
  27. var scheduler = new TestScheduler();
  28. var xs = scheduler.CreateHotObservable(
  29. OnNext(150, 1),
  30. OnCompleted<int>(250)
  31. );
  32. var res = scheduler.Start(() =>
  33. xs.SingleAsync()
  34. );
  35. res.Messages.AssertEqual(
  36. OnError<int>(250, e => e is InvalidOperationException)
  37. );
  38. xs.Subscriptions.AssertEqual(
  39. Subscribe(200, 250)
  40. );
  41. }
  42. [TestMethod]
  43. public void SingleAsync_One()
  44. {
  45. var scheduler = new TestScheduler();
  46. var xs = scheduler.CreateHotObservable(
  47. OnNext(150, 1),
  48. OnNext(210, 2),
  49. OnCompleted<int>(250)
  50. );
  51. var res = scheduler.Start(() =>
  52. xs.SingleAsync()
  53. );
  54. res.Messages.AssertEqual(
  55. OnNext(250, 2),
  56. OnCompleted<int>(250)
  57. );
  58. xs.Subscriptions.AssertEqual(
  59. Subscribe(200, 250)
  60. );
  61. }
  62. [TestMethod]
  63. public void SingleAsync_Many()
  64. {
  65. var scheduler = new TestScheduler();
  66. var xs = scheduler.CreateHotObservable(
  67. OnNext(150, 1),
  68. OnNext(210, 2),
  69. OnNext(220, 3),
  70. OnCompleted<int>(250)
  71. );
  72. var res = scheduler.Start(() =>
  73. xs.SingleAsync()
  74. );
  75. res.Messages.AssertEqual(
  76. OnError<int>(220, e => e is InvalidOperationException)
  77. );
  78. xs.Subscriptions.AssertEqual(
  79. Subscribe(200, 220)
  80. );
  81. }
  82. [TestMethod]
  83. public void SingleAsync_Error()
  84. {
  85. var scheduler = new TestScheduler();
  86. var ex = new Exception();
  87. var xs = scheduler.CreateHotObservable(
  88. OnNext(150, 1),
  89. OnError<int>(210, ex)
  90. );
  91. var res = scheduler.Start(() =>
  92. xs.SingleAsync()
  93. );
  94. res.Messages.AssertEqual(
  95. OnError<int>(210, ex)
  96. );
  97. xs.Subscriptions.AssertEqual(
  98. Subscribe(200, 210)
  99. );
  100. }
  101. [TestMethod]
  102. public void SingleAsync_Predicate()
  103. {
  104. var scheduler = new TestScheduler();
  105. var xs = scheduler.CreateHotObservable(
  106. OnNext(150, 1),
  107. OnNext(210, 2),
  108. OnNext(220, 3),
  109. OnNext(230, 4),
  110. OnNext(240, 5),
  111. OnCompleted<int>(250)
  112. );
  113. var res = scheduler.Start(() =>
  114. xs.SingleAsync(x => x % 2 == 1)
  115. );
  116. res.Messages.AssertEqual(
  117. OnError<int>(240, e => e is InvalidOperationException)
  118. );
  119. xs.Subscriptions.AssertEqual(
  120. Subscribe(200, 240)
  121. );
  122. }
  123. [TestMethod]
  124. public void SingleAsync_Predicate_Empty()
  125. {
  126. var scheduler = new TestScheduler();
  127. var ex = new Exception();
  128. var xs = scheduler.CreateHotObservable(
  129. OnNext(150, 1),
  130. OnCompleted<int>(250)
  131. );
  132. var res = scheduler.Start(() =>
  133. xs.SingleAsync(x => x % 2 == 1)
  134. );
  135. res.Messages.AssertEqual(
  136. OnError<int>(250, e => e is InvalidOperationException)
  137. );
  138. xs.Subscriptions.AssertEqual(
  139. Subscribe(200, 250)
  140. );
  141. }
  142. [TestMethod]
  143. public void SingleAsync_Predicate_One()
  144. {
  145. var scheduler = new TestScheduler();
  146. var xs = scheduler.CreateHotObservable(
  147. OnNext(150, 1),
  148. OnNext(210, 2),
  149. OnNext(220, 3),
  150. OnNext(230, 4),
  151. OnNext(240, 5),
  152. OnCompleted<int>(250)
  153. );
  154. var res = scheduler.Start(() =>
  155. xs.SingleAsync(x => x == 4)
  156. );
  157. res.Messages.AssertEqual(
  158. OnNext(250, 4),
  159. OnCompleted<int>(250)
  160. );
  161. xs.Subscriptions.AssertEqual(
  162. Subscribe(200, 250)
  163. );
  164. }
  165. [TestMethod]
  166. public void SingleAsync_Predicate_Throw()
  167. {
  168. var scheduler = new TestScheduler();
  169. var ex = new Exception();
  170. var xs = scheduler.CreateHotObservable(
  171. OnNext(150, 1),
  172. OnError<int>(210, ex)
  173. );
  174. var res = scheduler.Start(() =>
  175. xs.SingleAsync(x => x > 10)
  176. );
  177. res.Messages.AssertEqual(
  178. OnError<int>(210, ex)
  179. );
  180. xs.Subscriptions.AssertEqual(
  181. Subscribe(200, 210)
  182. );
  183. }
  184. [TestMethod]
  185. public void SingleAsync_PredicateThrows()
  186. {
  187. var scheduler = new TestScheduler();
  188. var ex = new Exception();
  189. var xs = scheduler.CreateHotObservable(
  190. OnNext(150, 1),
  191. OnNext(210, 2),
  192. OnNext(220, 3),
  193. OnNext(230, 4),
  194. OnNext(240, 5),
  195. OnCompleted<int>(250)
  196. );
  197. var res = scheduler.Start(() =>
  198. xs.SingleAsync(x => { if (x < 4) { return false; } throw ex; })
  199. );
  200. res.Messages.AssertEqual(
  201. OnError<int>(230, ex)
  202. );
  203. xs.Subscriptions.AssertEqual(
  204. Subscribe(200, 230)
  205. );
  206. }
  207. [TestMethod] // https://github.com/dotnet/reactive/issues/1235
  208. public void MeaningfulStackTrace()
  209. {
  210. static async Task Core()
  211. {
  212. static void AssertException(Exception e)
  213. {
  214. Assert.IsType<InvalidOperationException>(e);
  215. Assert.NotNull(e.StackTrace);
  216. Assert.NotEqual("", e.StackTrace);
  217. Assert.True(e.StackTrace.Contains("SingleAsync"));
  218. }
  219. var xs = Observable.Range(0, 2).SingleAsync();
  220. try
  221. {
  222. await xs;
  223. }
  224. catch (Exception e)
  225. {
  226. AssertException(e);
  227. }
  228. try
  229. {
  230. await xs.ToTask();
  231. }
  232. catch (Exception e)
  233. {
  234. AssertException(e);
  235. }
  236. var tcs = new TaskCompletionSource<bool>();
  237. xs.Subscribe(
  238. _ => { },
  239. e => tcs.SetException(e),
  240. () => tcs.SetResult(false));
  241. try
  242. {
  243. await tcs.Task;
  244. }
  245. catch (Exception e)
  246. {
  247. AssertException(e);
  248. }
  249. }
  250. Core().GetAwaiter().GetResult();
  251. }
  252. }
  253. }