UsingTest.cs 9.8 KB

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