UsingTest.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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;
  6. using System.Reactive.Disposables;
  7. using System.Reactive.Linq;
  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 UsingTest : ReactiveTest
  16. {
  17. [TestMethod]
  18. public void Using_ArgumentChecking()
  19. {
  20. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Using(null, DummyFunc<IDisposable, IObservable<int>>.Instance));
  21. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Using(DummyFunc<IDisposable>.Instance, (Func<IDisposable, IObservable<int>>)null));
  22. ReactiveAssert.Throws</*some*/Exception>(() => Observable.Using(() => DummyDisposable.Instance, d => default(IObservable<int>)).Subscribe());
  23. ReactiveAssert.Throws<ArgumentNullException>(() => Observable.Using(() => DummyDisposable.Instance, d => DummyObservable<int>.Instance).Subscribe(null));
  24. }
  25. [TestMethod]
  26. public void Using_Null()
  27. {
  28. var scheduler = new TestScheduler();
  29. var disposeInvoked = 0L;
  30. var createInvoked = 0L;
  31. var xs = default(ITestableObservable<long>);
  32. var disposable = default(MockDisposable);
  33. var _d = default(MockDisposable);
  34. var res = scheduler.Start(() =>
  35. Observable.Using(
  36. () =>
  37. {
  38. disposeInvoked++;
  39. disposable = default;
  40. return disposable;
  41. },
  42. d =>
  43. {
  44. _d = d;
  45. createInvoked++;
  46. xs = scheduler.CreateColdObservable(
  47. OnNext(100, scheduler.Clock),
  48. OnCompleted<long>(200));
  49. return xs;
  50. }
  51. )
  52. );
  53. Assert.Same(disposable, _d);
  54. res.Messages.AssertEqual(
  55. OnNext(300, 200L),
  56. OnCompleted<long>(400)
  57. );
  58. Assert.Equal(1, createInvoked);
  59. Assert.Equal(1, disposeInvoked);
  60. xs.Subscriptions.AssertEqual(
  61. Subscribe(200, 400)
  62. );
  63. Assert.Null(disposable);
  64. }
  65. [TestMethod]
  66. public void Using_Complete()
  67. {
  68. var scheduler = new TestScheduler();
  69. var disposeInvoked = 0;
  70. var createInvoked = 0;
  71. var xs = default(ITestableObservable<long>);
  72. var disposable = default(MockDisposable);
  73. var _d = default(MockDisposable);
  74. var res = scheduler.Start(() =>
  75. Observable.Using(
  76. () =>
  77. {
  78. disposeInvoked++;
  79. disposable = new MockDisposable(scheduler);
  80. return disposable;
  81. },
  82. d =>
  83. {
  84. _d = d;
  85. createInvoked++;
  86. xs = scheduler.CreateColdObservable(
  87. OnNext(100, scheduler.Clock),
  88. OnCompleted<long>(200));
  89. return xs;
  90. }
  91. )
  92. );
  93. Assert.Same(disposable, _d);
  94. res.Messages.AssertEqual(
  95. OnNext(300, 200L),
  96. OnCompleted<long>(400)
  97. );
  98. Assert.Equal(1, createInvoked);
  99. Assert.Equal(1, disposeInvoked);
  100. xs.Subscriptions.AssertEqual(
  101. Subscribe(200, 400)
  102. );
  103. disposable.AssertEqual(
  104. 200,
  105. 400
  106. );
  107. }
  108. [TestMethod]
  109. public void Using_Error()
  110. {
  111. var scheduler = new TestScheduler();
  112. var disposeInvoked = 0;
  113. var createInvoked = 0;
  114. var xs = default(ITestableObservable<long>);
  115. var disposable = default(MockDisposable);
  116. var _d = default(MockDisposable);
  117. var ex = new Exception();
  118. var res = scheduler.Start(() =>
  119. Observable.Using(
  120. () =>
  121. {
  122. disposeInvoked++;
  123. disposable = new MockDisposable(scheduler);
  124. return disposable;
  125. },
  126. d =>
  127. {
  128. _d = d;
  129. createInvoked++;
  130. xs = scheduler.CreateColdObservable(
  131. OnNext(100, scheduler.Clock),
  132. OnError<long>(200, ex));
  133. return xs;
  134. }
  135. )
  136. );
  137. Assert.Same(disposable, _d);
  138. res.Messages.AssertEqual(
  139. OnNext(300, 200L),
  140. OnError<long>(400, ex)
  141. );
  142. Assert.Equal(1, createInvoked);
  143. Assert.Equal(1, disposeInvoked);
  144. xs.Subscriptions.AssertEqual(
  145. Subscribe(200, 400)
  146. );
  147. disposable.AssertEqual(
  148. 200,
  149. 400
  150. );
  151. }
  152. [TestMethod]
  153. public void Using_Dispose()
  154. {
  155. var scheduler = new TestScheduler();
  156. var disposeInvoked = 0;
  157. var createInvoked = 0;
  158. var xs = default(ITestableObservable<long>);
  159. var disposable = default(MockDisposable);
  160. var _d = default(MockDisposable);
  161. var res = scheduler.Start(() =>
  162. Observable.Using(
  163. () =>
  164. {
  165. disposeInvoked++;
  166. disposable = new MockDisposable(scheduler);
  167. return disposable;
  168. },
  169. d =>
  170. {
  171. _d = d;
  172. createInvoked++;
  173. xs = scheduler.CreateColdObservable(
  174. OnNext(100, scheduler.Clock),
  175. OnNext(1000, scheduler.Clock + 1));
  176. return xs;
  177. }
  178. )
  179. );
  180. Assert.Same(disposable, _d);
  181. res.Messages.AssertEqual(
  182. OnNext(300, 200L)
  183. );
  184. Assert.Equal(1, createInvoked);
  185. Assert.Equal(1, disposeInvoked);
  186. xs.Subscriptions.AssertEqual(
  187. Subscribe(200, 1000)
  188. );
  189. disposable.AssertEqual(
  190. 200,
  191. 1000
  192. );
  193. }
  194. [TestMethod]
  195. public void Using_ThrowResourceSelector()
  196. {
  197. var scheduler = new TestScheduler();
  198. var disposeInvoked = 0;
  199. var createInvoked = 0;
  200. var ex = new Exception();
  201. var res = scheduler.Start(() =>
  202. Observable.Using<int, IDisposable>(
  203. () =>
  204. {
  205. disposeInvoked++;
  206. throw ex;
  207. },
  208. d =>
  209. {
  210. createInvoked++;
  211. return Observable.Never<int>();
  212. }
  213. )
  214. );
  215. res.Messages.AssertEqual(
  216. OnError<int>(200, ex)
  217. );
  218. Assert.Equal(0, createInvoked);
  219. Assert.Equal(1, disposeInvoked);
  220. }
  221. [TestMethod]
  222. public void Using_ThrowResourceUsage()
  223. {
  224. var scheduler = new TestScheduler();
  225. var ex = new Exception();
  226. var disposeInvoked = 0;
  227. var createInvoked = 0;
  228. var disposable = default(MockDisposable);
  229. var res = scheduler.Start(() =>
  230. Observable.Using<int, IDisposable>(
  231. () =>
  232. {
  233. disposeInvoked++;
  234. disposable = new MockDisposable(scheduler);
  235. return disposable;
  236. },
  237. d =>
  238. {
  239. createInvoked++;
  240. throw ex;
  241. }
  242. )
  243. );
  244. res.Messages.AssertEqual(
  245. OnError<int>(200, ex)
  246. );
  247. Assert.Equal(1, createInvoked);
  248. Assert.Equal(1, disposeInvoked);
  249. disposable.AssertEqual(
  250. 200,
  251. 200
  252. );
  253. }
  254. [TestMethod]
  255. public void Using_NestedCompleted()
  256. {
  257. var order = "";
  258. Observable.Using(() => Disposable.Create(() => order += "3"),
  259. _ => Observable.Using(() => Disposable.Create(() => order += "2"),
  260. __ => Observable.Using(() => Disposable.Create(() => order += "1"),
  261. ___ => Observable.Return(Unit.Default))))
  262. .Finally(() => order += "4")
  263. .Subscribe();
  264. Assert.Equal("1234", order);
  265. }
  266. [TestMethod]
  267. public void Using_NestedDisposed()
  268. {
  269. var order = "";
  270. Observable.Using(() => Disposable.Create(() => order += "3"),
  271. _ => Observable.Using(() => Disposable.Create(() => order += "2"),
  272. __ => Observable.Using(() => Disposable.Create(() => order += "1"),
  273. ___ => Observable.Never<Unit>())))
  274. .Finally(() => order += "4")
  275. .Subscribe()
  276. .Dispose();
  277. Assert.Equal("1234", order);
  278. }
  279. }
  280. }